Code Refactored
This commit is contained in:
@@ -41,7 +41,12 @@
|
||||
const INTEGER_FIELDS = new Set(["applicationId", "portfolioId", "bankBranchId", "residenceColonyId",
|
||||
"officeColonyId", "propertyColonyId", "formMode"]);
|
||||
const element = (id) => document.getElementById(id);
|
||||
const value = (id) => element(id)?.value?.trim() ?? "";
|
||||
const value = (id) => {
|
||||
const field = element(id);
|
||||
if (!field) return "";
|
||||
window.CygnusFormValidation.sanitizeElement(field);
|
||||
return field.value?.trim() ?? "";
|
||||
};
|
||||
const integer = (id) => {
|
||||
const parsed = Number.parseInt(value(id), 10);
|
||||
return Number.isFinite(parsed) ? parsed : 0;
|
||||
@@ -74,24 +79,14 @@
|
||||
notify("danger", "APP-4221", "At least one verification type is required.");
|
||||
return false;
|
||||
}
|
||||
window.invalidFields = 0;
|
||||
window.validate(element("applno"), "t", "AlphaNumeric");
|
||||
window.validate(element("bank_branch_id"), "t", "");
|
||||
window.validate(element("product"), "t", "");
|
||||
window.validate(element("customername"), "t", "AlphaSpace");
|
||||
window.validate(element("apptype"), "t", "");
|
||||
if (checked("rv")) window.CheckForm(element("rv"), "raddr1,raddr2,raddr3,rlandmark,colr,rcity,rpincode", "t,f,t,f,t,t,f", "SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode");
|
||||
if (checked("ov")) window.CheckForm(element("ov"), "companyname,oaddr1,oaddr2,oaddr3,olandmark,colo,ocity,opincode,department,designation", "f,t,f,t,f,t,t,f,f,f", "SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode,SplInstruction,SplInstruction");
|
||||
if (checked("pv")) window.CheckForm(element("pv"), "paddr1,paddr2,paddr3,plandmark,colp,pcity,ppincode", "t,f,t,f,t,t,f", "SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode");
|
||||
if (checked("rtv")) window.CheckForm(element("rtv"), "rphone", "t", "Phone");
|
||||
if (checked("otv")) window.CheckForm(element("otv"), "ophone", "t", "Phone");
|
||||
if (checked("refv")) window.CheckForm(element("refv"), "refname1,refaddress1,refcontactno1", "t,f,t", "AlphaSpace,SplInstruction,Phone");
|
||||
const validation = window.CygnusInitiationValidation.validateForm();
|
||||
[["rv", "Rcolony", "colr"], ["ov", "Ocolony", "colo"], ["pv", "Pcolony", "colp"]]
|
||||
.forEach(([flag, hidden, visible]) => {
|
||||
if (checked(flag) && integer(hidden) === 0) window.highlightField(element(visible));
|
||||
});
|
||||
if (document.querySelector(".matrix-validation-error-icon")) {
|
||||
if (!validation.valid || document.querySelector(".matrix-validation-error-icon")) {
|
||||
notify("danger", "APP-4221", "Correct the highlighted fields and submit the application again.");
|
||||
validation.invalid[0]?.focus();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -0,0 +1,75 @@
|
||||
(function (window, document) {
|
||||
"use strict";
|
||||
|
||||
const element = (id) => document.getElementById(id);
|
||||
const checked = (id) => Boolean(element(id)?.checked);
|
||||
const requiredWhen = (id) => () => checked(id);
|
||||
const sectionRule = (id, rule = {}) => Object.assign({ when: requiredWhen(id) }, rule);
|
||||
const RULES = {
|
||||
applno: { required: true, format: "AlphaNumeric", requiredMessage: "Application number is required." },
|
||||
bank_branch_id: { required: true, requiredMessage: "Bank branch is required." },
|
||||
product: { required: true, requiredMessage: "Product is required." },
|
||||
customername: { required: true, format: "AlphaSpace", requiredMessage: "Customer name is required." },
|
||||
apptype: { required: true, requiredMessage: "Application type is required." },
|
||||
bankcode: { format: "AlphaNumeric" }, fathername: { format: "AlphaSpace" }, dob: { format: "Date" },
|
||||
mobileno: { format: "AllowWrong" }, loanamount: { format: "LoanAmount" },
|
||||
contactperson: { format: "AlphaSpace" }, specialinst: { format: "SplInstruction" },
|
||||
raddr1: sectionRule("rv", { required: true, format: "SplInstruction" }), raddr2: sectionRule("rv", { format: "SplInstruction" }),
|
||||
raddr3: sectionRule("rv", { required: true, format: "SplInstruction" }), rlandmark: sectionRule("rv", { format: "SplInstruction" }),
|
||||
rcity: sectionRule("rv", { required: true }), colr: sectionRule("rv", { required: true, format: "SplInstruction" }),
|
||||
rpincode: sectionRule("rv", { format: "Pincode" }), rphone: sectionRule("rtv", { required: true, format: "Phone" }),
|
||||
companyname: sectionRule("ov", { format: "SplInstruction" }), oaddr1: sectionRule("ov", { required: true, format: "SplInstruction" }),
|
||||
oaddr2: sectionRule("ov", { format: "SplInstruction" }), oaddr3: sectionRule("ov", { required: true, format: "SplInstruction" }),
|
||||
olandmark: sectionRule("ov", { format: "SplInstruction" }), ocity: sectionRule("ov", { required: true }),
|
||||
colo: sectionRule("ov", { required: true, format: "SplInstruction" }), opincode: sectionRule("ov", { format: "Pincode" }),
|
||||
department: sectionRule("ov", { format: "SplInstruction" }), designation: sectionRule("ov", { format: "SplInstruction" }),
|
||||
ophone: sectionRule("otv", { required: true, format: "Phone" }), extension: sectionRule("otv", { format: "Extension" }),
|
||||
paddr1: sectionRule("pv", { required: true, format: "SplInstruction" }), paddr2: sectionRule("pv", { format: "SplInstruction" }),
|
||||
paddr3: sectionRule("pv", { required: true, format: "SplInstruction" }), plandmark: sectionRule("pv", { format: "SplInstruction" }),
|
||||
pcity: sectionRule("pv", { required: true }), colp: sectionRule("pv", { required: true, format: "SplInstruction" }),
|
||||
ppincode: sectionRule("pv", { format: "Pincode" }), refname1: sectionRule("refv", { required: true, format: "AlphaSpace" }),
|
||||
refaddress1: sectionRule("refv", { format: "SplInstruction" }),
|
||||
refcontactno1: sectionRule("refv", { required: true, format: "Phone" }),
|
||||
refname2: sectionRule("refv", { format: "AlphaSpace" }), refaddress2: sectionRule("refv", { format: "SplInstruction" }),
|
||||
refcontactno2: sectionRule("refv", { format: "Phone" })
|
||||
};
|
||||
|
||||
function registerDynamicRules(form) {
|
||||
if (!form) return;
|
||||
form.querySelectorAll("#FormPanel6 [data-validation-required]").forEach(function (field) {
|
||||
const label = field.closest(".widget")?.querySelector(".lblcontainer")?.textContent.trim();
|
||||
RULES[field.id] = {
|
||||
required: field.dataset.validationRequired === "true",
|
||||
format: field.dataset.validationFormat || "",
|
||||
requiredMessage: (label || "This dynamic field") + " is required."
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function validateField(field) {
|
||||
const target = typeof field === "string" ? element(field) : field;
|
||||
const rule = target && RULES[target.id];
|
||||
return !target || !rule || window.CygnusFormValidation.validateElement(target, rule);
|
||||
}
|
||||
|
||||
function validateForm() {
|
||||
return window.CygnusFormValidation.validateRules(RULES);
|
||||
}
|
||||
|
||||
function bind(form) {
|
||||
if (!form || form.dataset.initiationValidationBound === "true") return;
|
||||
registerDynamicRules(form);
|
||||
form.dataset.initiationValidationBound = "true";
|
||||
form.addEventListener("focusout", function (event) {
|
||||
window.CygnusFormValidation.sanitizeElement(event.target);
|
||||
validateField(event.target);
|
||||
});
|
||||
}
|
||||
|
||||
window.CygnusInitiationValidation = Object.freeze({
|
||||
rules: RULES,
|
||||
bind: bind,
|
||||
validateField: validateField,
|
||||
validateForm: validateForm
|
||||
});
|
||||
}(window, document));
|
||||
File diff suppressed because it is too large
Load Diff
150
cygnus-onprem-app/build/WebContent/js/lib/form-validation.js
Normal file
150
cygnus-onprem-app/build/WebContent/js/lib/form-validation.js
Normal file
@@ -0,0 +1,150 @@
|
||||
(function (window, document) {
|
||||
"use strict";
|
||||
|
||||
const FORMATS = Object.freeze({
|
||||
Email: /^\S*\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,8}\b\S*$/,
|
||||
Numeric: /^\d*$/,
|
||||
AlphaNumeric: /^[a-zA-Z0-9_*\/\-]*$/,
|
||||
AlphaSpace: /^[a-zA-Z0-9()\/ &]*$/,
|
||||
LoanAmount: /^[a-zA-Z0-9. ]*$/,
|
||||
SplInstruction: /^[a-zA-Z0-9():,#@.\-\/ ]*$/,
|
||||
Remarks: /^[a-zA-Z0-9,(),:+&#@'.\-\/ ]*$/,
|
||||
Pincode: /^\d{6}$/,
|
||||
Phone: /^((\d{6,8}|\d{10}|\d{3}-\d{6,8})([\/](\d{6,8}|\d{10}|\d{3}-\d{6,8})){0,2})$/,
|
||||
Extension: /^\d{3,4}$/
|
||||
});
|
||||
const DATE_PATTERN = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
|
||||
|
||||
function sanitize(value, options) {
|
||||
const multiline = Boolean(options && options.multiline);
|
||||
let sanitized = String(value == null ? "" : value).replace(/\t/g, "");
|
||||
if (multiline) {
|
||||
sanitized = sanitized.replace(/\r\n?/g, "\n").replace(/[^\x20-\x7E\n]/g, "");
|
||||
} else {
|
||||
sanitized = sanitized.replace(/[\r\n]/g, "").replace(/[^\x20-\x7E]/g, "");
|
||||
}
|
||||
return sanitized.trim();
|
||||
}
|
||||
|
||||
function sanitizeElement(element) {
|
||||
if (!element || typeof element.value !== "string") return "";
|
||||
const tagName = element.tagName ? element.tagName.toLowerCase() : "";
|
||||
const inputType = (element.type || "text").toLowerCase();
|
||||
const sanitizableInput = tagName === "input" &&
|
||||
["text", "search", "tel", "email", "url", "password"].includes(inputType);
|
||||
if (tagName !== "textarea" && !sanitizableInput) return element.value;
|
||||
const sanitized = sanitize(element.value, { multiline: tagName === "textarea" });
|
||||
if (element.value !== sanitized) element.value = sanitized;
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
function valueOf(element) {
|
||||
return element && typeof element.value === "string" ? element.value.trim() : "";
|
||||
}
|
||||
|
||||
function isEmpty(element) {
|
||||
const value = valueOf(element);
|
||||
return value === "" || (element.type === "select-one" && value === "-1");
|
||||
}
|
||||
|
||||
function isDate(value) {
|
||||
const parts = DATE_PATTERN.exec(value);
|
||||
if (!parts) return false;
|
||||
const day = Number(parts[1]);
|
||||
const month = Number(parts[2]);
|
||||
const year = Number(parts[3]);
|
||||
if (year < 1900 || year > 2100 || month < 1 || month > 12) return false;
|
||||
const date = new Date(year, month - 1, day);
|
||||
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
|
||||
}
|
||||
|
||||
function matchesFormat(value, format) {
|
||||
if (!value || !format || format === "AllowWrong") return true;
|
||||
const normalized = Object.keys(FORMATS).find((name) => name.toLowerCase() === format.toLowerCase());
|
||||
if (format.toLowerCase() === "date") return isDate(value);
|
||||
return normalized ? FORMATS[normalized].test(value) : true;
|
||||
}
|
||||
|
||||
function errorHost(element) {
|
||||
let current = element.parentNode;
|
||||
let host = current;
|
||||
while (current && current !== document.body) {
|
||||
if ((" " + (current.className || "") + " ").indexOf(" inputcontainer ") !== -1) return current;
|
||||
current = current.parentNode;
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
function clearError(element) {
|
||||
if (!element) return;
|
||||
const icon = document.getElementById("err" + element.id);
|
||||
if (icon && icon.parentNode) icon.parentNode.removeChild(icon);
|
||||
element.classList.remove("errtxt");
|
||||
if (element.parentNode) element.parentNode.classList.remove("errdiv");
|
||||
element.removeAttribute("aria-invalid");
|
||||
element.removeAttribute("aria-describedby");
|
||||
if (typeof element.setCustomValidity === "function") element.setCustomValidity("");
|
||||
}
|
||||
|
||||
function showError(element, message) {
|
||||
if (!element) return;
|
||||
clearError(element);
|
||||
const host = errorHost(element);
|
||||
const icon = document.createElement("img");
|
||||
icon.src = "/matrix/images/exclamation.png";
|
||||
icon.id = "err" + element.id;
|
||||
icon.alt = message;
|
||||
icon.title = message;
|
||||
icon.className = "matrix-validation-error-icon" +
|
||||
(element.type === "select-one" ? " matrix-validation-error-icon--select" : "");
|
||||
icon.style.cssText = "position:absolute;right:" + (element.type === "select-one" ? "24px" : "5px") +
|
||||
";top:50%;width:14px;height:14px;transform:translateY(-50%);z-index:3;pointer-events:none";
|
||||
host.style.position = "relative";
|
||||
host.appendChild(icon);
|
||||
if (element.type === "select-one") element.parentNode.classList.add("errdiv");
|
||||
else element.classList.add("errtxt");
|
||||
element.setAttribute("aria-invalid", "true");
|
||||
element.setAttribute("aria-describedby", icon.id);
|
||||
if (typeof element.setCustomValidity === "function") element.setCustomValidity(message);
|
||||
}
|
||||
|
||||
function validateElement(element, rule) {
|
||||
if (!element) return true;
|
||||
sanitizeElement(element);
|
||||
if (typeof rule.when === "function" && !rule.when()) {
|
||||
clearError(element);
|
||||
return true;
|
||||
}
|
||||
const required = typeof rule.required === "function" ? rule.required() : Boolean(rule.required);
|
||||
let message = "";
|
||||
if (required && isEmpty(element)) message = rule.requiredMessage || "This field is required.";
|
||||
else if (!isEmpty(element) && !matchesFormat(valueOf(element), rule.format)) {
|
||||
message = rule.formatMessage || "Enter a valid value.";
|
||||
}
|
||||
if (message) showError(element, message);
|
||||
else clearError(element);
|
||||
return message === "";
|
||||
}
|
||||
|
||||
function validateLegacy(element, requiredFlag, format) {
|
||||
return validateElement(element, { required: requiredFlag === "t", format: format });
|
||||
}
|
||||
|
||||
function validateRules(rules) {
|
||||
const invalid = [];
|
||||
Object.keys(rules).forEach(function (id) {
|
||||
const element = document.getElementById(id);
|
||||
if (!validateElement(element, rules[id])) invalid.push(element);
|
||||
});
|
||||
return { valid: invalid.length === 0, invalid: invalid };
|
||||
}
|
||||
|
||||
window.CygnusFormValidation = Object.freeze({
|
||||
clearError: clearError,
|
||||
sanitize: sanitize,
|
||||
sanitizeElement: sanitizeElement,
|
||||
validateElement: validateElement,
|
||||
validateLegacy: validateLegacy,
|
||||
validateRules: validateRules
|
||||
});
|
||||
}(window, document));
|
||||
@@ -74,5 +74,22 @@
|
||||
document.getElementById("cygnus-notifications")?.replaceChildren();
|
||||
}
|
||||
|
||||
window.CygnusNotifications = Object.freeze({ show, clear });
|
||||
function showLegacy(serialized, options) {
|
||||
const text = String(serialized || "");
|
||||
const firstSeparator = text.indexOf(":");
|
||||
const secondSeparator = firstSeparator < 0 ? -1 : text.indexOf(":", firstSeparator + 1);
|
||||
const settings = Object.assign({}, options);
|
||||
if (secondSeparator > firstSeparator) {
|
||||
settings.code = text.slice(0, firstSeparator);
|
||||
const legacyType = text.slice(firstSeparator + 1, secondSeparator).toLowerCase();
|
||||
settings.type = legacyType === "error" ? "danger" : legacyType;
|
||||
settings.message = text.slice(secondSeparator + 1);
|
||||
} else {
|
||||
settings.type = settings.type || "danger";
|
||||
settings.message = text;
|
||||
}
|
||||
return show(settings);
|
||||
}
|
||||
|
||||
window.CygnusNotifications = Object.freeze({ show, showLegacy, clear });
|
||||
}(window, document));
|
||||
|
||||
Reference in New Issue
Block a user