-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
diff --git a/src/demo/index2.html b/src/demo/index2.html
deleted file mode 100644
index 02924e9..0000000
--- a/src/demo/index2.html
+++ /dev/null
@@ -1,114 +0,0 @@
-
-
-
-
-
Demo 2 | Javascript Validator
-
-
-
-
-
-
-
-
-
-
diff --git a/src/demo/index3.html b/src/demo/index3.html
deleted file mode 100644
index 1123857..0000000
--- a/src/demo/index3.html
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
-
-
Demo 2 | Javascript Validator
-
-
-
-
-
Input Client Information
-
-
-
-
-
-
-
diff --git a/src/js/formValidator.es6.js b/src/js/formValidator.es6.js
index 7a6f659..5af1008 100644
--- a/src/js/formValidator.es6.js
+++ b/src/js/formValidator.es6.js
@@ -1,10 +1,10 @@
/*!
- * JavaScript Validator Library v1.0
+ * JavaScript Validator Library v2.0
* To perform effective validation and filter with form elements.
*
* Author : Shankar Thiyagaraajan
* Email : shankarthiyagaraajan@gmail.com
- * Github : https://github.com/shankarThiyagaraajan
+ * GitHub : https://github.com/shankarThiyagaraajan
*
* Source
* https://github.com/global-source/javascript_form_validator
@@ -17,17 +17,20 @@
* Released under the MIT license
* https://github.com/global-source/javascript_form_validator/blob/master/LICENSE
*
- * Date: 2017-05-01
+ * Date: 2017-08-03
*/
-/**
+
+/*
* For Managing overall Validation flow.
*/
+let __err_id_suffix_rand_hash = '_new1_1_1xv_resp';
+let __status_log = false;
+/**
+ * Core Js Validator.
+ */
class jsValidator {
- /*
- * jsValidator's Constructor.
- */
constructor() {
// Holding form element data.
this.formData = false;
@@ -41,8 +44,6 @@ class jsValidator {
this.jsFormError = false;
// Overall error list.
this.formErrorList = {};
- // Common Logger Instance.
- this.jsFilter = false;
// To Filter non-required fields.
this.forceFilter = false;
// To Filter the First load.
@@ -51,30 +52,31 @@ class jsValidator {
this.option = false;
// To apply global validator.
this.onChange = false;
+ this.validateResponse = false;
}
/*
* Initiating the Validator.
*/
init(option) {
- this.jsFilter = new jsFilter(option.forceFilter);
-
- jsLogger.table(option);
-
+ // Update overall log status.
+ __status_log = option.log;
// To Update global options.
this.option = option;
+ jsLogger.table(option);
// Updating the filter flag to global.
- // this.onlyFilter = option.onlyFilter;
+ this.onlyFilter = option.onlyFilter;
// To Enable/Disable global validator.
this.onChange = option.onChange;
+ // Update default response "class".
+ if ('undefined' === typeof option.errorClass) option.errorClass = 'js-error-cop';
+ this.validateResponse = new validationResponse();
// Update "jsSettings" to global object.
this.jsSettings = new jsSettings().init(option);
// Update "jsForm" to global object.
this.jsForm = new jsForm().init(option);
// Initiate form error setup.
this.jsFormError = new jsFormError().init();
- // Initiate Rule Sets.
- this.jsRuleSets = new jsRuleSets();
// Update Force Field status.
this.forceFilter = option.forceFilter;
// To check the form elements.
@@ -83,64 +85,61 @@ class jsValidator {
this.submitListener(this.jsForm.formCore, this);
// Send back "this".
return this;
- }
+ };
/*
* To make listen on submit action of the form.
*/
submitListener(formID, obj) {
// To off submit listener, if only filter needed.
- if (false === this.onlyFilter || typeof(this.onlyFilter) === 'undefined') {
+ if (false === this.onlyFilter || typeof (this.onlyFilter) === 'undefined') {
// Initiate listener for form submission.
- document.querySelector("#" + formID).addEventListener("submit", function (e) {
-
- // To start form validations and authorize.
+ document.querySelector('#' + formID).addEventListener('submit', function (e) {
+ // To start form validations.
+ // Check validation status.
if (false === obj.check()) {
//stop form from submitting, if validation fails
e.preventDefault();
}
});
}
- }
+ };
/*
- * To update the DOM to make action listener.
+ * To Refresh the DOM and enable Dynamic-Elements to Access.
*/
update() {
- // To Update global options.
let option = this.option;
+ // Updating the filter flag to global.
+ this.onlyFilter = option.onlyFilter;
// Update "jsSettings" to global object.
this.jsSettings = new jsSettings().init(option);
// Update "jsForm" to global object.
this.jsForm = new jsForm().init(option);
// Initiate form error setup.
this.jsFormError = new jsFormError().init();
- }
+ };
/*
* To checking all elements from registered form.
*/
check() {
+ let status = false;
// Loading JS Form.
let jsFormObj = this.jsForm;
// Loading JS error list.
let errorList = this.formErrorList;
- // Overall validation status.
- let status = false;
-
let option = [];
-
// Looping the "input" elements for validation and filter implementation.
errorList.input = this.elemLoop('input', jsFormObj.input);
// Looping the "textArea" elements fro validation filter implementation.
errorList.textArea = this.elemLoop('textArea', jsFormObj.textArea);
// Looping the "select" elements fro validation filter implementation.
errorList.select = this.elemLoop('select', jsFormObj.select);
-
- option.push({'errorElem': errorList});
-
- jsLogger.out('Error List', option);
-
+ jsLogger.out('Error List', this.formErrorList);
+ option.push({
+ 'errorElem': errorList
+ });
// To Update global Validation Status.
// If, Input elements have no errors.
if (errorList.input.length === 0) {
@@ -148,17 +147,16 @@ class jsValidator {
if (errorList.textArea.length === 0) {
// If, Select elements have no errors.
if (errorList.select.length === 0) {
- // If validation pass, then update "validationPass" object.
+ // If validation pass, then update "status" object.
status = true;
}
}
}
- if (false == this.initialLoad) validationResponse.init(errorList, this.option);
-
+ if (false == this.initialLoad) this.validateResponse.init(errorList, this.option);
this.initialLoad = false;
-
+ helper.scrollToError(this.validateResponse);
return status;
- }
+ };
/*
* To looping all elements for actions.
@@ -166,13 +164,13 @@ class jsValidator {
elemLoop(index, formElem) {
// Initiate empty array for keep list of errors.
let log = [];
+ // Sanity check with "formElem".
if (formElem === null || typeof formElem === 'undefined') return false;
- // To Reverse the loop to start notify from first element.
formElem = formElem.reverse();
// Looping elements.
for (let i in formElem) {
if (formElem[i]) {
- // Switch to static variable.
+ // Switch to static letiable.
let activeElem = formElem[i];
// Apply filter to element.
this.applyFilters(activeElem);
@@ -180,52 +178,55 @@ class jsValidator {
if (true == this.onChange) {
this.applyGlobalListener(activeElem);
}
+ //jsLogger.out('Only Filter', this.onlyFilter);
// If not only filter, then start validations.
- if (false === this.onlyFilter || 'undefined' === this.onlyFilter) {
+ if (false === this.onlyFilter || typeof (this.onlyFilter) === 'undefined') {
// Initiate validations and update to log.
- log = this.jsRuleSets.constructor.checkValidation(activeElem, log);
+ log = new jsRuleSets().checkValidation(activeElem, log);
}
}
}
+ // jsLogger.out('Log', log);
return log;
- }
+ };
/*
* To apply filter to all relevant elements by it's attributes.
*/
applyFilters(activeElem) {
// Apply filter for Number elements.
- if (activeElem.type == 'number') this.jsFilter.number(activeElem);
+ if (activeElem.type == 'number') new jsFilter().number(activeElem);
// Apply filter for Email elements.
- if (activeElem.type == 'email') this.jsFilter.constructor.email(activeElem);
+ if (activeElem.type == 'email') new jsFilter().email(activeElem);
// Apply filter for Numeric elements.
- // if (activeElem.min || activeElem.max) this.jsFilter.limit(activeElem);
+ if ('' !== activeElem.min || '' !== activeElem.max || activeElem.getAttribute('data-maxlength') || -1 !== activeElem.maxLength) new jsFilter().limit(activeElem);
+ // Apply filter File elements.
+ if (activeElem.type == 'file') new jsFilter().file(activeElem);
// Apply filter with string, alphaNumeric and pregMatch.
- if (activeElem.getAttribute('data-allow')) this.jsFilter.string(activeElem);
+ if (activeElem.getAttribute('data-allow')) new jsFilter().string(activeElem);
// Apply filter with pattern.
- if (activeElem.getAttribute('pattern')) jsFilter.pattern(activeElem);
- }
+ if (activeElem.getAttribute('pattern')) new jsFilter().pattern(activeElem);
+ };
/*
* To make it active to listen changes of those error fields.
*/
applyGlobalListener(element) {
- var current = this;
- element.addEventListener("change", current.constructor.quickValidation, false);
- }
+ element.addEventListener('change', this.quickValidation, false);
+ };
/*
* To perform quick validation to respond those fields.
*/
- static quickValidation(event) {
- jsLogger.out('Quick', event);
- var log = [];
- var target = event.target;
- jsLogger.out('Target', target);
- log = new jsRuleSets().constructor.checkValidation(target, log);
- jsLogger.out('Quick Out', log);
- validationResponse.process(log);
- }
+ quickValidation(event) {
+ // jsLogger.out('Quick', event);
+ let log = [];
+ let target = event.target;
+ // To check the validation of an element.
+ log = new jsRuleSets().checkValidation(target, log);
+ // jsLogger.out('Quick Out', log);
+ new validationResponse().process(log);
+ };
/*
* Single step instance validator for Ajax form submissions.
@@ -233,35 +234,29 @@ class jsValidator {
validate() {
// Initiate form Check.
return this.check();
- }
+ };
}
-
/**
* Common Filter instances.
*/
class jsFilter {
- /*
- * jsFilter's Constructor.
- */
- constructor(forceFilter) {
- this.forceFilter = forceFilter;
- }
-
- /*
- * Number elements filter listener.
- */
- number(element) {
- let current = this;
- let status = true;
- if (false === this.forceFilter) {
+ checkStatus(elem) {
+ let status;
+ status = true;
+ if (false === new jsValidator().forceFilter) {
status = false;
- if (true === element.required) {
+ if (true === elem.required) {
status = true;
}
}
- if (true === status) element.addEventListener("keypress", current.constructor.isNumberKey, false);
+ return status;
+ };
- }
+ // Number elements filter listener.
+ number(element) {
+ let status = this.checkStatus(element);
+ if (true === status) element.addEventListener('keypress', this.isNumberKey, false);
+ };
/*
* String elements filter listener.
@@ -270,167 +265,187 @@ class jsFilter {
// Getting "data" attribute for actions.
let type = element.getAttribute('data-allow');
let current = this;
- let status = true;
-
- if (false == this.forceFilter) {
- status = false;
- if (true === element.required) {
- status = true;
- }
- }
+ let status = this.checkStatus(element);
// Switching actions.
switch (type) {
// Allow only alphabets [a-zA-Z] not [0-9] and special characters.
case 'onlyAlpha':
- if (true === status) element.addEventListener("keypress", current.constructor.isAlpha, false);
+ if (true === status) element.addEventListener('keypress', current.isAlpha, false);
break;
// Allow only alpha Numeric [a-zA-Z0-9] not special characters.
case 'string':
- if (true === status) element.addEventListener("keypress", current.constructor.isAlphaNumeric, false);
- break;
- // Allow only alpha Numeric [a-zA-Z0-9] not special characters.
- case 'password':
- if (true === status) element.addEventListener("keypress", current.constructor.isValidPassword, false);
+ if (true === status) element.addEventListener('keypress', current.isAlphaNumeric, false);
break;
// Allow based on the pattern given.
default:
- if (true === status) element.addEventListener("keypress", current.constructor.isPatternValid, false);
+ if (true === status) element.addEventListener('keypress', current.isPatternValid, false);
break;
}
- }
+ };
/*
* Pattern based filter and listener.
*/
- static pattern(element) {
- var current = this;
-
- var status = true;
- if (false === this.forceFilter) {
- status = false;
- if (true === element.required) {
- status = true;
- }
- }
-
- if (true === status) element.addEventListener("keypress", current.isPatternValid, false);
-
- }
+ pattern(element) {
+ let current = this;
+ let status = this.checkStatus(element);
+ if (true === status) element.addEventListener('keypress', current.isPatternValid, false);
+ };
/*
* Email elements filter listener.
*/
- static email(element) {
- //this.jsRuleSet = new jsRuleSets();
- //element.addEventListener("keypress", this.jsRuleSet.constructor.email, false);
- }
+ email(element) {
+ let status = this.checkStatus(element);
+ if (true === status) element.addEventListener('keypress', jsRuleSets.email, false);
+ };
+
+ file(element) {
+ let status = this.checkStatus(element);
+ if (true === status) element.addEventListener('change', jsRuleSets.file, false);
+ };
/*
* Numeric with Limited elements filter listener.
*/
limit(element) {
- let status = true;
- if (false === this.forceFilter) {
- status = false;
- if (true === element.required) {
- status = true;
- }
- }
- if (true === status) element.addEventListener("keypress", this.constructor.isInLimit, false);
-
- }
+ let current = this;
+ let status = this.checkStatus(element);
+ if (true === status) element.addEventListener('change', current.isInLimit, false);
+ };
- //TODO: fix live entry issue.
/*
* Restrict element with it's limit.
*/
- static isInLimit(event) {
+ isInLimit(event) {
+
+ // Load the element value.
let value = event.target.value;
+
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
+ // Getting target element.
+ let target = event.target;
+
+ // Final value to load back.
+ let final_value = value;
+
// Getting object from element.
let min = event.target.min;
let max = event.target.max;
- // Default values for Min and Max.
- if (!min) min = 0;
- if (!max) max = 54;
+ // Get max-length attribute from element.
+ let max_length = event.target.getAttribute('data-maxlength') ? event.target.getAttribute('data-maxlength') : 0;
+ max_length = parseInt(max_length);
+ let num = value;
- // Forming pattern for Restriction.
- let regex = new RegExp('^[0-9]+$');
- // Validation with Code.
- let key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
+ // if "max_length" is "0", then its don't have limit letiables.
+ if (0 === max_length) {
- // jsLogger.out('Limit', regex.test(key) + ' | min |' + min + ' | max | ' + max);
- // jsLogger.out('Regex', regex.test(key));
- // Return status of the Action.
- if (false === regex.test(key) || parseInt(value) > max || parseInt(value) < min) {
- event.preventDefault();
+ // Default values for Min and Max.
+ if (!min) min = 1;
+ if (!max) max = 100;
+
+ // Forming pattern for Restriction.
+ let regex = new RegExp('^[0-9]+$');
+
+ // Validation with Code.
+ let key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
+
+ // Return status of the Action.
+ if (false === regex.test(key) || parseInt(value) > max || parseInt(value) < min) {
+ event.preventDefault();
+ }
+
+ // Parse to INT.
+ num = parseInt(num, 10);
+
+ // // converts value to a Number.
+ if (isNaN(num)) {
+ target.value = "";
+ return;
+ }
+
+ // Check value is greater than "max", then replace "max".
+ if (parseInt(num) > max) final_value = max;
+
+ // Check value is greater than "min", then replace "min".
+ if (parseInt(num) < min) final_value = min;
+
+ } else {
+ //TODO: Min length later.
+ // Validate the length of the string.
+ if ((num.length > max_length) && 0 < max_length) {
+ // If length is more, then cutoff the remaining letters.
+ final_value = num.substr(0, max_length);
+ }
}
- // Updating the value.
- event.target.value = (event.target.value > max) ? max : event.target.value;
- }
+
+ // Revert value back to an element.
+ this.value = final_value;
+ };
/*
* Only allow alpha([a-zA-Z]).
*/
- static isAlpha(event) {
+ isAlpha(event) {
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
- let status = pattern.validate(event, 'a-zA-Z');
- console.log(status);
+ // Managing the Pattern.
+ let status = new pattern().validate(event, 'a-zA-Z');
// Return status of the Action.
if (false === status) event.preventDefault();
- }
+ };
/*
* Only allow alpha([a-zA-Z0-9]).
*/
- static isAlphaNumeric(event) {
+ isAlphaNumeric(event) {
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
// Managing the Pattern.
- let status = pattern.validate(event, 'a-zA-Z0-9');
+ let status = new pattern().validate(event, 'a-zA-Z0-9');
// Return status of the Action.
if (false === status) event.preventDefault();
- }
+ };
/*
* To check password is valid or not.
*/
- static isValidPassword(event) {
+ isValidPassword(event) {
// Prevent using "space".
let charCode = (event.which) ? event.which : event.keyCode;
+ // If event is "space" then prevent to enter.
if (charCode === 32) {
event.preventDefault();
return false;
- }
- // To check is this action is from "windows" action or not.
+ } // To check is this action is from "windows" action or not.
+
if (true === helper.isWindowAction(event)) return true;
// Managing the Pattern.
- let status = pattern.validate(event, 'a-zA-Z0-9');
+ let status = new pattern().validate(event, 'a-zA-Z0-9');
// Return status of the Action.
if (false === status) event.preventDefault();
- }
+ };
/*
* Only allow by pattern(ex. ^[a-zA-Z0-3@#$!_.]+$).
*/
- static isPatternValid(event) {
+ isPatternValid(event) {
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
// Managing the Pattern.
- let status = pattern.validate(event, 'a-zA-Z0-9');
+ let status = new pattern().validate(event, 'a-zA-Z0-4');
// Return status of the Action.
if (false === status) event.preventDefault();
- }
+ };
/*
* Check is numeric or not.
*/
- static isNumberKey(event) {
+ isNumberKey(event) {
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
// Validation with Code.
@@ -438,19 +453,16 @@ class jsFilter {
if (charCode === 46 || charCode > 31 && (charCode < 48 || charCode > 57)) {
event.preventDefault();
return false;
- }
- // Return status of the Action.
+ } // Return status of the Action.
+
return true;
- }
+ };
}
/**
* To Update overall JsValidator Settings.
*/
class jsSettings {
- /*
- * jsSetting's Constructor.
- */
constructor() {
// Common error message color for form validation.
this.errorColor = false;
@@ -468,27 +480,21 @@ class jsSettings {
this.errorTemplate = option.errorTemplate;
// Return "this" object.
return this;
- }
+ };
/*
* General Log.
*/
log() {
jsLogger.out(this.errorColor);
- jsLogger.out(this.followedElement);
jsLogger.out(this.errorTemplate);
- }
+ };
}
-
/**
* To Perform all Form based Operations.
*/
class jsForm {
- /*
- * jsForm's Constructor.
- */
constructor() {
- this.options = false;
// Form element.
this.form = false;
// Form ID.
@@ -509,7 +515,7 @@ class jsForm {
* To Initiating the "jsForm".
*/
init(option) {
- // jsLogger.out('Form', option.form);
+ jsLogger.out('Form', option.form);
// Update Global Option.
this.options = option;
// Enable/Disable Force Filter.
@@ -520,9 +526,8 @@ class jsForm {
this.parseForm(this.form);
// To Filter Required Elements.
this.required();
-
return this;
- }
+ };
/*
* To Register Active Form to Global Object.
@@ -530,25 +535,20 @@ class jsForm {
registerForm(form) {
// validate and Update Log.
if (typeof form === 'undefined') jsLogger.out('Form Identification', 'Form Identification is Missing !');
-
// Form should not be an ID.
if (null === form) return false;
-
// Fetch Form element from Document.
this.form = document.getElementById(form);
if (null === this.form) jsLogger.out('Status 503', 'Failed to Proceed !');
// Update Direct Form ID.
this.formCore = form;
- }
+ };
/*
* To Parse all Relative Form components.
*/
parseForm(form) {
-
- // Form should not be an ID.
- if (null === form) return false;
-
+ if (form === null) return false;
// "Input" elements like "text, date, time..."
this.input = form.getElementsByTagName('input');
// "Select" element.
@@ -557,7 +557,7 @@ class jsForm {
this.textArea = form.getElementsByTagName('textarea');
// "Label" element.
this.label = form.getElementsByTagName('label');
- }
+ };
/*
* To set fields are required.
@@ -565,13 +565,14 @@ class jsForm {
required() {
// let jsField = new jsField().init(this.options);
let forceFilter = this.forceFilter;
+ let jsField_obj = new jsField();
// Filter all required "input" elements.
- this.input = jsField.required(this.input, forceFilter);
+ this.input = jsField_obj.required(this.input, forceFilter);
// Filter all required "select" elements.
- this.select = jsField.required(this.select, forceFilter);
+ this.select = jsField_obj.required(this.select, forceFilter);
// Filter all required "textArea" elements.
- this.textArea = jsField.required(this.textArea, forceFilter);
- }
+ this.textArea = jsField_obj.required(this.textArea, forceFilter);
+ };
/*
* General Log.
@@ -582,151 +583,131 @@ class jsForm {
jsLogger.out('select', this.select);
jsLogger.out('textarea', this.textArea);
jsLogger.out('labels', this.label);
- }
+ };
}
-
/**
* Perform Operations in Field level.
*/
class jsField {
-
- /*
- * jsField's Constructor.
- */
- constructor() {
- this.forceFilter = false;
- }
-
- /*
- * To Initializing jsField.
- */
- init(option) {
- this.forceFilter = option.forceFilter;
- }
-
/*
* Return all required elements list.
*/
- static required(field, forceFilter) {
+ required(field, forceFilter) {
let requiredFieldsList = [];
+ // Looping fields to filter.
for (let i = 0; i < field.length; i++) {
// Check and push elements.
- // if (field[i].required === true) {
- if ((field[i].required === true) || true === forceFilter) {
+ if (field[i].required === true || true === forceFilter) {
// Pushing to required elements list.
requiredFieldsList.push(field[i]);
}
- }
- // Return list of required elements.
+ } // Return list of required elements.
+
return requiredFieldsList;
- }
+ };
}
-
/**
* List of Validation Rules.
*/
class jsRuleSets {
- /*
- * jsRuleSets's Constructor.
- */
- constructor() {
-
- }
-
/*
* To start validation process.
*/
- static checkValidation(activeElem, log) {
+ checkValidation(activeElem, log) {
+ //jsLogger.out('Active Elem', activeElem);
let validElem = true;
- let firstErrorHit = false;
+ let jsRuleSets_obj = new jsRuleSets();
// To Generally checks, the field is empty or not.
- if (!jsRuleSets.isSet(activeElem)) {
+ if (!jsRuleSets_obj.isSet(activeElem)) {
log.push({
'el': activeElem,
'type': 'required',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
- } // To Check the Value is less than min or not.
+ validElem = false;
+ }
+ // To Check the Value is less than minimum or not.
if (activeElem.min) {
- if (jsRuleSets.isSet(activeElem)) {
- if (!jsRuleSets.min(activeElem)) {
+ if (jsRuleSets_obj.isSet(activeElem)) {
+ if (!jsRuleSets_obj.min(activeElem)) {
log.push({
'el': activeElem,
'type': 'min',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
validElem = false;
}
}
- } // To Check the Value is grater than max or not.
+ }
+ // To Check the Value is grater than max or not.
if (activeElem.max) {
- if (jsRuleSets.isSet(activeElem)) {
- if (!jsRuleSets.max(activeElem)) {
+ if (jsRuleSets_obj.isSet(activeElem)) {
+ if (!jsRuleSets_obj.max(activeElem)) {
log.push({
'el': activeElem,
'type': 'max',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
validElem = false;
}
}
- } // To Check the Entered E-mail is Valid or Not.
+ }
+ // To Check the Entered E-mail is Valid or Not.
if (activeElem.type == 'email') {
- if (jsRuleSets.isSet(activeElem)) {
- if (!jsRuleSets.email(activeElem)) {
+ if (jsRuleSets_obj.isSet(activeElem)) {
+ if (!jsRuleSets_obj.email(activeElem)) {
log.push({
'el': activeElem,
'type': 'email',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
validElem = false;
}
}
- } // To Compare the Password is Same or Not with Re-Password.
- // TODO: Implement Simplified Comparison.
+ }
+ // To Compare the Password is Same or Not with Re-Password.
+ // TODO: Implement Simplified Comparison.
if (activeElem.type == 'password') {
- if (jsRuleSets.isSet(activeElem)) {
- if (!jsRuleSets.compare(activeElem)) {
+ if (jsRuleSets_obj.isSet(activeElem)) {
+ if (!jsRuleSets_obj.compare(activeElem)) {
log.push({
'el': activeElem,
'type': 'password',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
validElem = false;
}
}
} // If valid, then reset validation message.
if (true === validElem) {
- jsLogger.out('Valid Elem', activeElem);
+ //jsLogger.out('Valid Elem', activeElem);
if (activeElem.name !== '') {
- let elem = document.getElementById(activeElem.name + '_new1_1_1xv_resp');
+ let elem = document.getElementById(activeElem.name + __err_id_suffix_rand_hash);
if (typeof (elem) !== 'undefined' && elem !== null) {
- elem.innerHTML = '';
+ // Remove element to avoid un-necessary buffer.
+ elem.remove();
}
}
}
// If error occurred, then locate that error
- if (false !== firstErrorHit) {
- helper.scrollToItem(firstErrorHit);
+ if (false !== validElem) {
+ //
}
+
// Return overall log report of validation.
+
return log;
- }
+ };
/*
* To Check, whether the element have value or not.
*/
- static isSet(elem) {
+ isSet(elem) {
// If field is not required, then return "true".
if (false === elem.required) return true;
let status = true;
@@ -734,45 +715,45 @@ class jsRuleSets {
//TODO: Implement suitable solution for this.
if (value.length === 0 || value === '' || value === ' ' || value === '[]') status = false;
return status;
- }
+ };
/*
* To Check Element with Min Condition.
*/
- static min(elem) {
+ min(elem) {
// If field is not required, then return "true".
if (false === elem.required) return true;
let status = true;
let value = elem.value;
let min = elem.min;
//TODO: Implement suitable solution for this.
- if (value.length < min) status = false;
+ if (value.length < min && value.length != 0) status = false;
return status;
- }
+ };
/*
* To Check Element with Max Condition.
*/
- static max(elem) {
+ max(elem) {
// If field is not required, then return "true".
if (false === elem.required) return true;
let status = true;
let value = elem.value;
let max = elem.max;
//TODO: Implement suitable solution for this.
- if (value.length > max) status = false;
+ if (value.length > max && value.length != 0) status = false;
return status;
- }
+ };
/*
* To Check Element Email is Valid or Not.
*/
- static email(elem) {
+ email(elem) {
// If field is not required, then return "true".
if (false === elem.required) return true;
-
let status = false;
let email = elem.value;
+ if (typeof email === 'undefined') return false;
// To Validate Email.
// Convert to Native String Format.
email = email.toString();
@@ -781,60 +762,72 @@ class jsRuleSets {
// Valid Email.
status = true;
}
-
if (!email) status = false;
-
return status;
- }
+ };
+
+ file(elem) {
+ let list_to_allow = elem.target.getAttribute('data-extensions');
+ let target = elem.target;
+ let list_to_allow_array;
+ let file_response;
+ if ('' === list_to_allow) return true;
+ // Slit into array of extensions.
+ if (-1 === list_to_allow.indexOf(',')) {
+ list_to_allow_array = [list_to_allow];
+ } else {
+ list_to_allow_array = list_to_allow.split(',');
+ }
+ // Get file name.
+ let fileName = target.value;
+ // Convert to lower case for native validation.
+ fileName = fileName.toLowerCase();
+ file_response = (new RegExp('(' + list_to_allow_array.join('|').replace(/\./g, '\\.') + ')$')).test(fileName);
+ if (false === file_response) {
+ alert('Allowed file types are "' + list_to_allow + '" !');
+ // Reset file type.
+ elem.target.value = '';
+ return false;
+ }
+ return true;
+ };
/*
* To Check Element Phone Value is Valid or Not.
*/
- static phone(elem, pattern) {
+ phone(elem, pattern) {
// If field is not required, then return "true".
if (false === elem.required) return true;
let status = true;
if (elem.value === '') status = false;
return status;
- }
+ };
/*
* To Compare two Elements Values.
*/
- static compare(elem1) {
+ compare(elem1) {
let status = false;
-
// If field is not required, then return "true".
if (false === elem1.required) status = true;
-
let elem2_id = elem1.getAttribute('data-check');
-
if (typeof elem2_id == 'undefined' || elem2_id == null) status = false;
-
if (elem2_id === null) elem2_id = elem1.getAttribute('data-parent');
if (elem2_id === null) {
status = false;
} else {
elem2_id = elem2_id.toString();
-
let elem2 = document.getElementById(elem2_id);
-
if (elem1.value === elem2.value) status = true;
}
-
- jsLogger.out('Compare Status', status);
+ //jsLogger.out('Compare Status', status);
return status;
- }
+ };
}
-
-
/**
* To Manage JsValidator Errors.
*/
class jsFormError {
- /*
- * jsFormError's constructor.
- */
constructor() {
// Global constant to specify, error happened or not.
this.errorHit = false;
@@ -851,15 +844,14 @@ class jsFormError {
this.errorHit = false;
this.errorCss = 'border-color: red;border-radius: 5px;color: red;';
this.successCss = 'border-color: green;border-radius: 5px;color: green;';
-
- }
+ };
/*
* Form error log.
*/
log() {
// jsLogger.out('Form Error Hit', this.errorHit);
- }
+ };
/*
* Form error style.
@@ -867,17 +859,22 @@ class jsFormError {
style(css) {
this.errorCss = css.error;
this.successCss = css.success;
- }
+ };
}
-
/**
* For manage overall logging with validator.
*/
let jsLogger = {
+ status: function () {
+ // return jsValidator.option.log;
+ return __status_log;
+ },
/*
* Simple log with "heading" and "message".
*/
out: function (heading, message) {
+
+ if (true !== this.status()) return false;
console.log('======' + heading + '======');
console.log(message);
console.log('------------------------');
@@ -886,17 +883,19 @@ let jsLogger = {
* For bulk data logging.
*/
bulk: function (data) {
+ if (true !== this.status()) return false;
console.log(data);
},
/*
* For log data with table.
*/
table: function (data) {
+ if (true !== this.status()) return false;
console.table(data);
}
};
/**
- * General Helping methods.
+ * General Helping methods.jsField_obj
*/
let helper = {
/*
@@ -919,44 +918,73 @@ let helper = {
// Finally return "false" for general keys.
return false;
},
+ /*
+ * To Scroll Up / Down to notify the item that have validation message.
+ */
+ scrollToError: function (validateResponse) {
+ let dummy_id = '__header_error_target_temp';
+ let active_class = validateResponse.getClass();
+
+ if (false === active_class) {
+ jsLogger.out('Active Class Error', 'ACTIVE CLASS NOT DEFINED, GET :' + active_class);
+ return false;
+ }
+
+ if (0 === document.getElementsByClassName(active_class).length) return false;
+ // Getting current ID of the element.
+ let active_id = document.getElementsByClassName(active_class)[0].id;
+ // Update first element with dummy index ID.
+ document.getElementsByClassName(active_class)[0].setAttribute('id', dummy_id);
+ // Forming ID.
+ let id = document.getElementsByClassName(active_class)[0].id;
+ // Retrieve the element name.
+ let elem_name = active_id.replace(__err_id_suffix_rand_hash, '');
+ // Taking active element to navigate.
+ let top = document.getElementsByName(elem_name)[0].offsetTop;
+ // Format as ID.
+ id = '#' + id;
+ // Navigate to ID.
+ // window.location.href = id;
+ // Scroll to error element as close as possible.
+ window.scroll(0, parseInt(top) - 15);
+ // Restore with actual ID.
+ document.getElementsByClassName(active_class)[0].setAttribute('id', active_id);
+ // Remove the navigated value.
+ this.removeHash(id);
+ },
/*
* To Scroll Up / Down to notify the item that have validation message.
*/
scrollToItem: function (item) {
- // alert(item);
- location.href = '#' + item;
- // // Update by Tag Name.
- // let elem_name = item.nodeName;
- // // If Element is not valid, then return false.
- // if (!elem_name) return false;
- // if (null == elem_name) return false;
- // // Re-Fetching elements by its Name.
- // item = document.getElementsByName(elem_name);
- //
- // let diff = (item.offsetTop - window.scrollY) / 20;
- // if (!window._lastDiff) {
- // window._lastDiff = 0;
- // }
- // if (Math.abs(diff) > 2) {
- // window.scrollTo(0, (window.scrollY + diff));
- // clearTimeout(window._TO);
- // if (diff !== window._lastDiff) {
- // window._lastDiff = diff;
- // window._TO = setTimeout(this.scrollToItem, 100, item);
- // }
- // } else {
- // window.scrollTo(0, item.offsetTop)
- // }
+ // Form hash value.
+ let hash = item;
+ // If "#" is missing, then add back to the ID.
+ if (-1 === hash.indexOf('#')) hash = '#' + hash;
+ // Navigate with the hash value.
+ window.location.href = hash;
+ // Remove the navigated value.
+ this.removeHash(hash);
+ },
+ /*
+ * To remove the hash value from the URL.
+ */
+ removeHash: function (hash) {
+ // Getting the actual URL.
+ let path = window.location.href;
+ // Replacing the URL with specific hash value.
+ path = path.replace(hash, '');
+ // Update to url history.
+ window.history.pushState('', 'Title', path);
}
};
/**
* Simple library for Pattern.
*/
-let pattern = {
+class pattern {
/*
* To generate pattern from element attribute.
*/
- getDefault: function (event, originalPattern) {
+ getDefault(event, originalPattern) {
if (typeof originalPattern == 'undefined') originalPattern = '';
// Getting special characters list.
let allow_special = event.target.getAttribute('data-allowSpecial');
@@ -973,11 +1001,12 @@ let pattern = {
defaultPattern = '^[' + originalPattern + allow_special + ']+$';
}
return defaultPattern;
- },
+ };
+
/*
* To validate event with the pattern.
*/
- validate: function (event, pattern) {
+ validate(event, pattern) {
// Managing the Pattern.
let defaultPattern = this.getDefault(event, pattern);
// Validate with special formed pattern.
@@ -985,46 +1014,70 @@ let pattern = {
// Validation with Code.
let key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
return regex.test(key);
- }
-};
+ };
+}
/**
* To Manage all kind of error response.
*/
-let validationResponse = {
+class validationResponse {
+ constructor() {
+ this.active_class = false;
+ }
+
/*
* Initiating the Response handler.
*/
- init: function (errorList, option) {
+ init(errorList, option) {
this.errorMessage = option.message;
+ // Updating the class.
+ this.active_class = option.errorClass;
// let errorElements = option.errorElem;
// jsLogger.out('Errors', errorList);
this.input(errorList.input);
this.select(errorList.select);
this.textArea(errorList.textArea);
- },
+
+ };
+
/*
* To handle the "input" element.
*/
- input: function (elem) {
+ input(elem) {
+ // Initiate process for Input.
this.process(elem);
- },
+ };
+
/*
* To handle the "select" element.
*/
- select: function (elem) {
+ select(elem) {
+ // Initiate process for Select.
this.process(elem);
- },
+ };
+
+ /*
+ * To return active class for validation response style.
+ */
+ getClass() {
+ return this.active_class;
+ };
+
/*
* To handle the "textArea" element.
*/
- textArea: function (elem) {
+ textArea(elem) {
+ // Initiate process for TextArea.
this.process(elem);
- },
+ };
+
/*
* To process all handlers.
*/
- process: function (elem) {
+ process(elem) {
+ // Process with initial response.
let elementDefaultResponse = '';
+ // Get active class for error response element
+ let active_class = this.getClass();
for (let i in elem) {
// jsLogger.out('Element', document.getElementById(elem[i].id));
if (elem[i].el && true === elem[i].el.required) {
@@ -1040,33 +1093,36 @@ let validationResponse = {
// jsLogger.out('Element Found', false);
spanTag = document.createElement('span');
spanTag.setAttribute('id', activeElem.id);
+ spanTag.setAttribute('class', active_class);
spanTag.innerHTML = elementDefaultResponse;
} else {
// Re-use Existing response Message SPAN.
spanTag.innerHTML = elementDefaultResponse;
- // jsLogger.out('Element Found', true);
- } // jsLogger.out('Error Elem', activeElem.el);
+ }
// Append HTML response to the Element.
-
activeElem.el.parentNode.insertBefore(spanTag, activeElem.el.nextSibling);
}
}
- },
+ };
+
/*
* Perform template creation and update.
*/
- template: function (activeElem, errorType) {
- jsLogger.out('error Type 0', errorType);
+ template(activeElem, errorType) {
+ //jsLogger.out('error Type 0', errorType);
let errorIndex = '';
let activeError = '';
+ // Getting error response message from elemnet.
let elementDefaultResponse = activeElem.el.getAttribute('data-message');
if (typeof elementDefaultResponse === 'undefined' || elementDefaultResponse === '' || elementDefaultResponse === null) {
// Sanity check with error message object.
if (typeof this.errorMessage !== 'undefined' && typeof this.errorMessage[errorType] !== 'undefined') {
+ // Getting error type. [ex. Required, Min, Max...]
errorType = this.errorMessage[errorType];
- activeElem.el.getAttribute('data-message');
+
+ // activeElem.el.getAttribute('data-message');
if (errorType) {
- jsLogger.out('errorType', errorType);
+ //jsLogger.out('errorType', errorType);
activeError = errorType;
// If error type is Min or Max, then it will proceed responsive.
if (activeElem.type == 'min' || activeElem.type == 'max') {
@@ -1081,22 +1137,25 @@ let validationResponse = {
elementDefaultResponse = activeError;
}
return elementDefaultResponse;
- },
+ };
+
/*
* Default error handling messages.
* If user not specify the messages,
* then it will be replaces.
*/
- default: function (errorType) {
+ default(errorType) {
+ let active_class = this.getClass();
let errorMessages = {
- required: 'This field is required',
- min: 'This field length is too low.',
- max: 'This field length is exceeds the limit',
- password: 'Password does not match.',
- email: 'Email is not valid'
+ required: '
This field is required.',
+ min: '
This field length is too low.',
+ max: '
This field length is exceeds the limit.',
+ password: '
Password does not match.',
+ email: '
Email is not valid.',
+ file: '
This file is not allowed.'
};
if (typeof errorType !== 'string') return false;
if (typeof errorMessages[errorType] === 'undefined') return false;
return errorMessages[errorType];
- }
-};
+ };
+}
\ No newline at end of file
diff --git a/src/js/formValidator.es6.min.js b/src/js/formValidator.es6.min.js
index bc5c94b..23455c4 100644
--- a/src/js/formValidator.es6.min.js
+++ b/src/js/formValidator.es6.min.js
@@ -1,4 +1,63 @@
-/**
- * Created by shankar on 12/5/17.
+/*!
+ * JavaScript Validator Library v2.0
+ * To perform effective validation and filter with form elements.
+ *
+ * Author : Shankar Thiyagaraajan
+ * Email : shankarthiyagaraajan@gmail.com
+ * GitHub : https://github.com/shankarThiyagaraajan
+ *
+ * Source
+ * https://github.com/global-source/javascript_form_validator
+ *
+ * Site
+ * https://global-source.github.io/javascript_form_validator/
+ *
+ * Copyright 2017
+ *
+ * Released under the MIT license
+ * https://github.com/global-source/javascript_form_validator/blob/master/LICENSE
+ *
+ * Date: 2017-08-03
*/
-class jsValidator{constructor(){this.formData=!1,this.onlyFilter=!1,this.jsForm=!1,this.jsSettings=!1,this.jsFormError=!1,this.formErrorList={},this.jsFilter=!1,this.forceFilter=!1,this.initialLoad=!0,this.option=!1,this.onChange=!1}init(a){return this.jsFilter=new jsFilter(a.forceFilter),jsLogger.table(a),this.option=a,this.onChange=a.onChange,this.jsSettings=(new jsSettings).init(a),this.jsForm=(new jsForm).init(a),this.jsFormError=(new jsFormError).init(),this.jsRuleSets=new jsRuleSets,this.forceFilter=a.forceFilter,this.check(),this.submitListener(this.jsForm.formCore,this),this}submitListener(a,b){!1!==this.onlyFilter&&void 0!==this.onlyFilter||document.querySelector("#"+a).addEventListener("submit",function(a){!1===b.check()&&a.preventDefault()})}update(){let a=this.option;this.jsSettings=(new jsSettings).init(a),this.jsForm=(new jsForm).init(a),this.jsFormError=(new jsFormError).init()}check(){let a=this.jsForm,b=this.formErrorList,c=!1,d=[];return b.input=this.elemLoop("input",a.input),b.textArea=this.elemLoop("textArea",a.textArea),b.select=this.elemLoop("select",a.select),d.push({errorElem:b}),jsLogger.out("Error List",d),0===b.input.length&&0===b.textArea.length&&0===b.select.length&&(alert("Form Valid !"),c=!0),0==this.initialLoad&&validationResponse.init(b,this.option),this.initialLoad=!1,c}elemLoop(a,b){let c=[];if(null===b||void 0===b)return!1;for(let a in b)if(b[a]){let d=b[a];this.applyFilters(d),1==this.onChange&&this.applyGlobalListener(d),!1!==this.onlyFilter&&"undefined"!==this.onlyFilter||(c=this.jsRuleSets.constructor.checkValidation(d,c))}return c}applyFilters(a){"number"==a.type&&this.jsFilter.number(a),"email"==a.type&&this.jsFilter.constructor.email(a),a.getAttribute("data-allow")&&this.jsFilter.string(a),a.getAttribute("pattern")&&jsFilter.pattern(a)}applyGlobalListener(a){var b=this;a.addEventListener("change",b.constructor.quickValidation,!1)}static quickValidation(a){jsLogger.out("Quick",a);var b=[],c=a.target;jsLogger.out("Target",c),b=(new jsRuleSets).constructor.checkValidation(c,b),jsLogger.out("Quick Out",b),validationResponse.process(b)}validate(){return this.check()}}class jsFilter{constructor(a){this.forceFilter=a}number(a){let b=this,c=!0;!1===this.forceFilter&&(c=!1,!0===a.required&&(c=!0)),!0===c&&a.addEventListener("keypress",b.constructor.isNumberKey,!1)}string(a){let b=a.getAttribute("data-allow"),c=this,d=!0;switch(0==this.forceFilter&&(d=!1,!0===a.required&&(d=!0)),b){case"onlyAlpha":!0===d&&a.addEventListener("keypress",c.constructor.isAlpha,!1);break;case"string":!0===d&&a.addEventListener("keypress",c.constructor.isAlphaNumeric,!1);break;case"password":!0===d&&a.addEventListener("keypress",c.constructor.isValidPassword,!1);break;default:!0===d&&a.addEventListener("keypress",c.constructor.isPatternValid,!1)}}static pattern(a){var b=this,c=!0;!1===this.forceFilter&&(c=!1,!0===a.required&&(c=!0)),!0===c&&a.addEventListener("keypress",b.isPatternValid,!1)}static email(a){}limit(a){let b=!0;!1===this.forceFilter&&(b=!1,!0===a.required&&(b=!0)),!0===b&&a.addEventListener("keypress",this.constructor.isInLimit,!1)}static isInLimit(a){let b=a.target.value;if(!0===helper.isWindowAction(a))return!0;let c=a.target.min,d=a.target.max;c||(c=0),d||(d=54);let e=new RegExp("^[0-9]+$"),f=String.fromCharCode(a.charCode?a.charCode:a.which);(!1===e.test(f)||parseInt(b)>d||parseInt(b)
d?d:a.target.value}static isAlpha(a){if(!0===helper.isWindowAction(a))return!0;let b=pattern.validate(a,"a-zA-Z");console.log(b),!1===b&&a.preventDefault()}static isAlphaNumeric(a){if(!0===helper.isWindowAction(a))return!0;!1===pattern.validate(a,"a-zA-Z0-9")&&a.preventDefault()}static isValidPassword(a){return 32===(a.which?a.which:a.keyCode)?(a.preventDefault(),!1):!0===helper.isWindowAction(a)||void(!1===pattern.validate(a,"a-zA-Z0-9")&&a.preventDefault())}static isPatternValid(a){if(!0===helper.isWindowAction(a))return!0;!1===pattern.validate(a,"a-zA-Z0-9")&&a.preventDefault()}static isNumberKey(a){if(!0===helper.isWindowAction(a))return!0;let b=a.which?a.which:a.keyCode;return!(46===b||b>31&&(b<48||b>57))||(a.preventDefault(),!1)}}class jsSettings{constructor(){this.errorColor=!1,this.errorTemplate=!1}init(a){return this.errorColor=a.errorColor,this.errorTemplate=a.errorTemplate,this}log(){jsLogger.out(this.errorColor),jsLogger.out(this.followedElement),jsLogger.out(this.errorTemplate)}}class jsForm{constructor(){this.options=!1,this.form=!1,this.formCore=!1,this.input=!1,this.select=!1,this.textArea=!1,this.label=!1,this.forceFilter=!1}init(a){return this.options=a,this.forceFilter=a.forceFilter,this.registerForm(a.form),this.parseForm(this.form),this.required(),this}registerForm(a){if(void 0===a&&jsLogger.out("Form Identification","Form Identification is Missing !"),null===a)return!1;this.form=document.getElementById(a),null===this.form&&jsLogger.out("Status 503","Failed to Proceed !"),this.formCore=a}parseForm(a){if(null===a)return!1;this.input=a.getElementsByTagName("input"),this.select=a.getElementsByTagName("select"),this.textArea=a.getElementsByTagName("textarea"),this.label=a.getElementsByTagName("label")}required(){let a=this.forceFilter;this.input=jsField.required(this.input,a),this.select=jsField.required(this.select,a),this.textArea=jsField.required(this.textArea,a)}log(){jsLogger.out("Form",this.form),jsLogger.out("input",this.input),jsLogger.out("select",this.select),jsLogger.out("textarea",this.textArea),jsLogger.out("labels",this.label)}}class jsField{constructor(){this.forceFilter=!1}init(a){this.forceFilter=a.forceFilter}static required(a,b){let c=[];for(let d=0;dd&&(b=!1),b}static email(a){if(!1===a.required)return!0;var b=!1,c=a.value;return c=c.toString(),/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(c)&&(b=!0),c||(b=!1),b}static phone(a,b){if(!1===a.required)return!0;let c=!0;return""===a.value&&(c=!1),c}static compare(a){let b=!1;!1===a.required&&(b=!0);let c=a.getAttribute("data-check");if(void 0!==c&&null!=c||(b=!1),null===c&&(c=a.getAttribute("data-parent")),null===c)b=!1;else{c=c.toString();let d=document.getElementById(c);a.value===d.value&&(b=!0)}return jsLogger.out("Compare Status",b),b}}class jsFormError{constructor(){this.errorHit=!1,this.errorCss=!1,this.successCss=!1}init(){this.errorHit=!1,this.errorCss="border-color: red;border-radius: 5px;color: red;",this.successCss="border-color: green;border-radius: 5px;color: green;"}log(){}style(a){this.errorCss=a.error,this.successCss=a.success}}let jsLogger={out:function(a,b){console.log("======"+a+"======"),console.log(b),console.log("------------------------")},bulk:function(a){console.log(a)},table:function(a){console.table(a)}},helper={isWindowAction:function(a){let b=a||window.event,c=b.shiftKey||b.which;return 9===c||0===c||8===c||32===c||13===c||8===c||c>=35&&c<=40||(c=String.fromCharCode(c),0===c.length)},scrollToItem:function(a){let b=a.nodeName;if(!b)return!1;if(null==b)return!1;a=document.getElementsByName(b);var c=(a.offsetTop-window.scrollY)/20;window._lastDiff||(window._lastDiff=0),Math.abs(c)>2?(window.scrollTo(0,window.scrollY+c),clearTimeout(window._TO),c!==window._lastDiff&&(window._lastDiff=c,window._TO=setTimeout(this.scrollToItem,100,a))):window.scrollTo(0,a.offsetTop)}},pattern={getDefault:function(a,b){void 0===b&&(b="");let c=a.target.getAttribute("data-allowSpecial"),d=a.target.pattern;console.log(d.length);return c||null!==c||(c=""),c=c.toString(),""!==d&&d.length>0&&null!==d?d:"^["+b+c+"]+$"},validate:function(a,b){let c=this.getDefault(a,b),d=new RegExp(c),e=String.fromCharCode(a.charCode?a.charCode:a.which);return d.test(e)}},validationResponse={init:function(a,b){this.errorMessage=b.message,this.input(a.input),this.select(a.select),this.textArea(a.textArea)},input:function(a){this.process(a)},select:function(a){this.process(a)},textArea:function(a){this.process(a)},process:function(a){let b="";for(let c in a)if(a[c].el&&!0===a[c].el.required){let d=a[c],e=a[c].type;b=this.template(d,e);let f=document.getElementById(d.id);void 0===f||null===f?(f=document.createElement("span"),f.setAttribute("id",d.id),f.innerHTML=b):f.innerHTML=b,d.el.parentNode.insertBefore(f,d.el.nextSibling)}},template:function(a,b){jsLogger.out("error Type 0",b);let c="",d="",e=a.el.getAttribute("data-message");return void 0!==e&&""!==e&&null!==e||(void 0!==this.errorMessage&&void 0!==this.errorMessage[b]?(b=this.errorMessage[b],a.el.getAttribute("data-message"),b&&(jsLogger.out("errorType",b),d=b,"min"!=a.type&&"max"!=a.type||("min"==a.type&&(c=a.el.min),"max"==a.type&&(c=a.el.max),d=d.replace("[INDEX]",c)))):d=this.default(b),e=d),e},default:function(a){let b={required:"This field is required",min:"This field length is too low.",max:"This field length is exceeds the limit",password:"Password does not match.",email:"Email is not valid"};return"string"==typeof a&&(void 0!==b[a]&&b[a])}};
\ No newline at end of file
+
+let __err_id_suffix_rand_hash='_new1_1_1xv_resp';let __status_log=!1;class jsValidator{constructor(){this.formData=!1;this.onlyFilter=!1;this.jsForm=!1;this.jsSettings=!1;this.jsFormError=!1;this.formErrorList={};this.forceFilter=!1;this.initialLoad=!0;this.option=!1;this.onChange=!1;this.validateResponse=!1}
+ init(option){__status_log=option.log;this.option=option;jsLogger.table(option);this.onlyFilter=option.onlyFilter;this.onChange=option.onChange;if('undefined'===typeof option.errorClass)option.errorClass='js-error-cop';this.validateResponse=new validationResponse();this.jsSettings=new jsSettings().init(option);this.jsForm=new jsForm().init(option);this.jsFormError=new jsFormError().init();this.forceFilter=option.forceFilter;this.check();this.submitListener(this.jsForm.formCore,this);return this};submitListener(formID,obj){if(!1===this.onlyFilter||typeof(this.onlyFilter)==='undefined'){document.querySelector('#'+formID).addEventListener('submit',function(e){if(!1===obj.check()){e.preventDefault()}})}};update(){let option=this.option;this.onlyFilter=option.onlyFilter;this.jsSettings=new jsSettings().init(option);this.jsForm=new jsForm().init(option);this.jsFormError=new jsFormError().init()};check(){let status=!1;let jsFormObj=this.jsForm;let errorList=this.formErrorList;let option=[];errorList.input=this.elemLoop('input',jsFormObj.input);errorList.textArea=this.elemLoop('textArea',jsFormObj.textArea);errorList.select=this.elemLoop('select',jsFormObj.select);jsLogger.out('Error List',this.formErrorList);option.push({'errorElem':errorList});if(errorList.input.length===0){if(errorList.textArea.length===0){if(errorList.select.length===0){status=!0}}}
+ if(!1==this.initialLoad)this.validateResponse.init(errorList,this.option);this.initialLoad=!1;helper.scrollToError(this.validateResponse);return status};elemLoop(index,formElem){let log=[];if(formElem===null||typeof formElem==='undefined')return!1;formElem=formElem.reverse();for(let i in formElem){if(formElem[i]){let activeElem=formElem[i];this.applyFilters(activeElem);if(!0==this.onChange){this.applyGlobalListener(activeElem)}
+ if(!1===this.onlyFilter||typeof(this.onlyFilter)==='undefined'){log=new jsRuleSets().checkValidation(activeElem,log)}}}
+ return log};applyFilters(activeElem){if(activeElem.type=='number')new jsFilter().number(activeElem);if(activeElem.type=='email')new jsFilter().email(activeElem);if(''!==activeElem.min||''!==activeElem.max||activeElem.getAttribute('data-maxlength')||-1!==activeElem.maxLength)new jsFilter().limit(activeElem);if(activeElem.type=='file')new jsFilter().file(activeElem);if(activeElem.getAttribute('data-allow'))new jsFilter().string(activeElem);if(activeElem.getAttribute('pattern'))new jsFilter().pattern(activeElem)};applyGlobalListener(element){element.addEventListener('change',this.quickValidation,!1)};quickValidation(event){let log=[];let target=event.target;log=new jsRuleSets().checkValidation(target,log);new validationResponse().process(log)};validate(){return this.check()}}
+class jsFilter{checkStatus(elem){let status;status=!0;if(!1===new jsValidator().forceFilter){status=!1;if(!0===elem.required){status=!0}}
+ return status};number(element){let status=this.checkStatus(element);if(!0===status)element.addEventListener('keypress',this.isNumberKey,!1)};string(element){let type=element.getAttribute('data-allow');let current=this;let status=this.checkStatus(element);switch(type){case 'onlyAlpha':if(!0===status)element.addEventListener('keypress',current.isAlpha,!1);break;case 'string':if(!0===status)element.addEventListener('keypress',current.isAlphaNumeric,!1);break;default:if(!0===status)element.addEventListener('keypress',current.isPatternValid,!1);break}};pattern(element){let current=this;let status=this.checkStatus(element);if(!0===status)element.addEventListener('keypress',current.isPatternValid,!1)};email(element){let status=this.checkStatus(element);if(!0===status)element.addEventListener('keypress',jsRuleSets.email,!1)};file(element){let status=this.checkStatus(element);if(!0===status)element.addEventListener('change',jsRuleSets.file,!1)};limit(element){let current=this;let status=this.checkStatus(element);if(!0===status)element.addEventListener('change',current.isInLimit,!1)};isInLimit(event){let value=event.target.value;if(!0===helper.isWindowAction(event))return!0;let target=event.target;let final_value=value;let min=event.target.min;let max=event.target.max;let max_length=event.target.getAttribute('data-maxlength')?event.target.getAttribute('data-maxlength'):0;max_length=parseInt(max_length);let num=value;if(0===max_length){if(!min)min=1;if(!max)max=100;let regex=new RegExp('^[0-9]+$');let key=String.fromCharCode(!event.charCode?event.which:event.charCode);if(!1===regex.test(key)||parseInt(value)>max||parseInt(value)max)final_value=max;if(parseInt(num)max_length)&&031&&(charCode<48||charCode>57)){event.preventDefault();return!1}
+ return!0}}
+class jsSettings{constructor(){this.errorColor=!1;this.errorTemplate=!1}
+ init(option){this.errorColor=option.errorColor;this.errorTemplate=option.errorTemplate;return this};log(){jsLogger.out(this.errorColor);jsLogger.out(this.errorTemplate)}}
+class jsForm{constructor(){this.form=!1;this.formCore=!1;this.input=!1;this.select=!1;this.textArea=!1;this.label=!1;this.forceFilter=!1}
+ init(option){jsLogger.out('Form',option.form);this.options=option;this.forceFilter=option.forceFilter;this.registerForm(option.form);this.parseForm(this.form);this.required();return this};registerForm(form){if(typeof form==='undefined')jsLogger.out('Form Identification','Form Identification is Missing !');if(null===form)return!1;this.form=document.getElementById(form);if(null===this.form)jsLogger.out('Status 503','Failed to Proceed !');this.formCore=form};parseForm(form){if(form===null)return!1;this.input=form.getElementsByTagName('input');this.select=form.getElementsByTagName('select');this.textArea=form.getElementsByTagName('textarea');this.label=form.getElementsByTagName('label')};required(){let forceFilter=this.forceFilter;let jsField_obj=new jsField();this.input=jsField_obj.required(this.input,forceFilter);this.select=jsField_obj.required(this.select,forceFilter);this.textArea=jsField_obj.required(this.textArea,forceFilter)};log(){jsLogger.out('Form',this.form);jsLogger.out('input',this.input);jsLogger.out('select',this.select);jsLogger.out('textarea',this.textArea);jsLogger.out('labels',this.label)}}
+class jsField{required(field,forceFilter){let requiredFieldsList=[];for(let i=0;imax&&value.length!=0)status=!1;return status};email(elem){if(!1===elem.required)return!0;let status=!1;let email=elem.value;if(typeof email==='undefined')return!1;email=email.toString();if(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)){status=!0}
+ if(!email)status=!1;return status};file(elem){let list_to_allow=elem.target.getAttribute('data-extensions');let target=elem.target;let list_to_allow_array;let file_response;if(''===list_to_allow)return!0;if(-1===list_to_allow.indexOf(',')){list_to_allow_array=[list_to_allow]}else{list_to_allow_array=list_to_allow.split(',')}
+ let fileName=target.value;fileName=fileName.toLowerCase();file_response=(new RegExp('('+list_to_allow_array.join('|').replace(/\./g,'\\.')+')$')).test(fileName);if(!1===file_response){alert('Allowed file types are "'+list_to_allow+'" !');elem.target.value='';return!1}
+ return!0};phone(elem,pattern){if(!1===elem.required)return!0;let status=!0;if(elem.value==='')status=!1;return status};compare(elem1){let status=!1;if(!1===elem1.required)status=!0;let elem2_id=elem1.getAttribute('data-check');if(typeof elem2_id=='undefined'||elem2_id==null)status=!1;if(elem2_id===null)elem2_id=elem1.getAttribute('data-parent');if(elem2_id===null){status=!1}else{elem2_id=elem2_id.toString();let elem2=document.getElementById(elem2_id);if(elem1.value===elem2.value)status=!0}
+ return status}}
+class jsFormError{constructor(){this.errorHit=!1;this.errorCss=!1;this.successCss=!1}
+ init(){this.errorHit=!1;this.errorCss='border-color: red;border-radius: 5px;color: red;';this.successCss='border-color: green;border-radius: 5px;color: green;'};log(){};style(css){this.errorCss=css.error;this.successCss=css.success}}
+let jsLogger={status:function(){return __status_log},out:function(heading,message){if(!0!==this.status())return!1;console.log('======'+heading+'======');console.log(message);console.log('------------------------')},bulk:function(data){if(!0!==this.status())return!1;console.log(data)},table:function(data){if(!0!==this.status())return!1;console.table(data)}};let helper={isWindowAction:function(event){let theEvent=event||window.event;let key=theEvent.shiftKey||theEvent.which;if(key===9||key===0||key===8||key===32||key===13||key===8||(key>=35&&key<=40)){return!0}
+ key=String.fromCharCode(key);if(key.length===0)return!0;return!1},scrollToError:function(validateResponse){let dummy_id='__header_error_target_temp';let active_class=validateResponse.getClass();if(!1===active_class){jsLogger.out('Active Class Error','ACTIVE CLASS NOT DEFINED, GET :'+active_class);return!1}
+ if(0===document.getElementsByClassName(active_class).length)return!1;let active_id=document.getElementsByClassName(active_class)[0].id;document.getElementsByClassName(active_class)[0].setAttribute('id',dummy_id);let id=document.getElementsByClassName(active_class)[0].id;let elem_name=active_id.replace(__err_id_suffix_rand_hash,'');let top=document.getElementsByName(elem_name)[0].offsetTop;id='#'+id;window.scroll(0,parseInt(top)-15);document.getElementsByClassName(active_class)[0].setAttribute('id',active_id);this.removeHash(id)},scrollToItem:function(item){let hash=item;if(-1===hash.indexOf('#'))hash='#'+hash;window.location.href=hash;this.removeHash(hash)},removeHash:function(hash){let path=window.location.href;path=path.replace(hash,'');window.history.pushState('','Title',path)}};class pattern{getDefault(event,originalPattern){if(typeof originalPattern=='undefined')originalPattern='';let allow_special=event.target.getAttribute('data-allowSpecial');let pattern=event.target.pattern;console.log(pattern.length);let defaultPattern;if(!allow_special&&allow_special===null)allow_special='';allow_special=allow_special.toString();if(pattern!==''&&pattern.length>0&&pattern!==null){defaultPattern=pattern}else{defaultPattern='^['+originalPattern+allow_special+']+$'}
+ return defaultPattern};validate(event,pattern){let defaultPattern=this.getDefault(event,pattern);let regex=new RegExp(defaultPattern);let key=String.fromCharCode(!event.charCode?event.which:event.charCode);return regex.test(key)}}
+class validationResponse{constructor(){this.active_class=!1}
+ init(errorList,option){this.errorMessage=option.message;this.active_class=option.errorClass;this.input(errorList.input);this.select(errorList.select);this.textArea(errorList.textArea)};input(elem){this.process(elem)};select(elem){this.process(elem)};getClass(){return this.active_class};textArea(elem){this.process(elem)};process(elem){let elementDefaultResponse='';let active_class=this.getClass();for(let i in elem){if(elem[i].el&&!0===elem[i].el.required){let activeElem=elem[i];let errorType=elem[i].type;elementDefaultResponse=this.template(activeElem,errorType);let spanTag=document.getElementById(activeElem.id);if(typeof spanTag==='undefined'||spanTag==='undefined'||spanTag===null){spanTag=document.createElement('span');spanTag.setAttribute('id',activeElem.id);spanTag.setAttribute('class',active_class);spanTag.innerHTML=elementDefaultResponse}else{spanTag.innerHTML=elementDefaultResponse}
+ activeElem.el.parentNode.insertBefore(spanTag,activeElem.el.nextSibling)}}};template(activeElem,errorType){let errorIndex='';let activeError='';let elementDefaultResponse=activeElem.el.getAttribute('data-message');if(typeof elementDefaultResponse==='undefined'||elementDefaultResponse===''||elementDefaultResponse===null){if(typeof this.errorMessage!=='undefined'&&typeof this.errorMessage[errorType]!=='undefined'){errorType=this.errorMessage[errorType];if(errorType){activeError=errorType;if(activeElem.type=='min'||activeElem.type=='max'){if('min'==activeElem.type)errorIndex=activeElem.el.min;if('max'==activeElem.type)errorIndex=activeElem.el.max;activeError=activeError.replace('[INDEX]',errorIndex)}}}else{activeError=this.default(errorType)}
+ elementDefaultResponse=activeError}
+ return elementDefaultResponse};default(errorType){let active_class=this.getClass();let errorMessages={required:'This field is required.',min:'This field length is too low.',max:'This field length is exceeds the limit.',password:'Password does not match.',email:'Email is not valid.',file:'This file is not allowed.'};if(typeof errorType!=='string')return!1;if(typeof errorMessages[errorType]==='undefined')return!1;return errorMessages[errorType]}}
\ No newline at end of file
diff --git a/src/js/formValidator.js b/src/js/formValidator.js
index d4563ee..8a94c78 100644
--- a/src/js/formValidator.js
+++ b/src/js/formValidator.js
@@ -1,10 +1,10 @@
/*!
- * JavaScript Validator Library v1.0
+ * JavaScript Validator Library v2.0
* To perform effective validation and filter with form elements.
*
* Author : Shankar Thiyagaraajan
* Email : shankarthiyagaraajan@gmail.com
- * Github : https://github.com/shankarThiyagaraajan
+ * GitHub : https://github.com/shankarThiyagaraajan
*
* Source
* https://github.com/global-source/javascript_form_validator
@@ -17,41 +17,45 @@
* Released under the MIT license
* https://github.com/global-source/javascript_form_validator/blob/master/LICENSE
*
- * Date: 2017-07-21
+ * Date: 2017-08-03
*/
/*
* For Managing overall Validation flow.
*/
-var firstErrorHit = false;
+var __err_id_suffix_rand_hash = '_new1_1_1xv_resp';
+var __status_log = false;
/**
* Core Js Validator.
*/
-var jsValidator = {
+function jsValidator() {
// Holding form element data.
- formData: false,
+ this.formData = false;
// Switch complete validation and input filter.
- onlyFilter: false,
+ this.onlyFilter = false;
// JS form.
- jsForm: false,
+ this.jsForm = false;
// JS setting.
- jsSettings: false,
+ this.jsSettings = false;
// JS form error.
- jsFormError: false,
+ this.jsFormError = false;
// Overall error list.
- formErrorList: {},
+ this.formErrorList = {};
// To Filter non-required fields.
- forceFilter: false,
+ this.forceFilter = false;
// To Filter the First load.
- initialLoad: true,
+ this.initialLoad = true;
// Global options.
- option: false,
+ this.option = false;
// To apply global validator.
- onChange: false,
+ this.onChange = false;
+ this.validateResponse = false;
/*
* Initiating the Validator.
*/
- init: function (option) {
+ this.init = function (option) {
+ // Update overall log status.
+ __status_log = option.log;
// To Update global options.
this.option = option;
jsLogger.table(option);
@@ -61,12 +65,13 @@ var jsValidator = {
this.onChange = option.onChange;
// Update default response "class".
if ('undefined' === typeof option.errorClass) option.errorClass = 'js-error-cop';
+ this.validateResponse = new validationResponse();
// Update "jsSettings" to global object.
- this.jsSettings = jsSettings.init(option);
+ this.jsSettings = new jsSettings().init(option);
// Update "jsForm" to global object.
- this.jsForm = jsForm.init(option);
+ this.jsForm = new jsForm().init(option);
// Initiate form error setup.
- this.jsFormError = jsFormError.init();
+ this.jsFormError = new jsFormError().init();
// Update Force Field status.
this.forceFilter = option.forceFilter;
// To check the form elements.
@@ -75,11 +80,11 @@ var jsValidator = {
this.submitListener(this.jsForm.formCore, this);
// Send back "this".
return this;
- },
+ };
/*
* To make listen on submit action of the form.
*/
- submitListener: function (formID, obj) {
+ this.submitListener = function (formID, obj) {
// To off submit listener, if only filter needed.
if (false === this.onlyFilter || typeof (this.onlyFilter) === 'undefined') {
// Initiate listener for form submission.
@@ -92,25 +97,25 @@ var jsValidator = {
}
});
}
- },
+ };
/*
* To Refresh the DOM and enable Dynamic-Elements to Access.
*/
- update: function () {
+ this.update = function () {
var option = this.option;
// Updating the filter flag to global.
this.onlyFilter = option.onlyFilter;
// Update "jsSettings" to global object.
- this.jsSettings = jsSettings.init(option);
+ this.jsSettings = new jsSettings().init(option);
// Update "jsForm" to global object.
- this.jsForm = jsForm.init(option);
+ this.jsForm = new jsForm().init(option);
// Initiate form error setup.
- this.jsFormError = jsFormError.init();
- },
+ this.jsFormError = new jsFormError().init();
+ };
/*
* To checking all elements from registered form.
*/
- check: function () {
+ this.check = function () {
var status = false;
// Loading JS Form.
var jsFormObj = this.jsForm;
@@ -139,15 +144,15 @@ var jsValidator = {
}
}
}
- if (false == this.initialLoad) validationResponse.init(errorList, this.option);
+ if (false == this.initialLoad) this.validateResponse.init(errorList, this.option);
this.initialLoad = false;
- helper.scrollToError();
+ helper.scrollToError(this.validateResponse);
return status;
- },
+ };
/*
* To looping all elements for actions.
*/
- elemLoop: function (index, formElem) {
+ this.elemLoop = function (index, formElem) {
// Initiate empty array for keep list of errors.
var log = [];
// Sanity check with "formElem".
@@ -168,79 +173,80 @@ var jsValidator = {
// If not only filter, then start validations.
if (false === this.onlyFilter || typeof (this.onlyFilter) === 'undefined') {
// Initiate validations and update to log.
- log = jsRuleSets.checkValidation(activeElem, log);
+ log = new jsRuleSets().checkValidation(activeElem, log);
}
}
}
// jsLogger.out('Log', log);
return log;
- },
+ };
/*
* To apply filter to all relevant elements by it's attributes.
*/
- applyFilters: function (activeElem) {
+ this.applyFilters = function (activeElem) {
// Apply filter for Number elements.
- if (activeElem.type == 'number') jsFilter.number(activeElem);
+ if (activeElem.type == 'number') new jsFilter().number(activeElem);
// Apply filter for Email elements.
- if (activeElem.type == 'email') jsFilter.email(activeElem);
+ if (activeElem.type == 'email') new jsFilter().email(activeElem);
// Apply filter for Numeric elements.
- if (activeElem.min || activeElem.max || activeElem.minLength || activeElem.maxLength) jsFilter.limit(activeElem);
+ if ('' !== activeElem.min || '' !== activeElem.max || activeElem.getAttribute('data-maxlength') || -1 !== activeElem.maxLength) new jsFilter().limit(activeElem);
// Apply filter File elements.
- if (activeElem.type == 'file') jsFilter.file(activeElem);
+ if (activeElem.type == 'file') new jsFilter().file(activeElem);
// Apply filter with string, alphaNumeric and pregMatch.
- if (activeElem.getAttribute('data-allow')) jsFilter.string(activeElem);
+ if (activeElem.getAttribute('data-allow')) new jsFilter().string(activeElem);
// Apply filter with pattern.
- if (activeElem.getAttribute('pattern')) jsFilter.pattern(activeElem);
- },
+ if (activeElem.getAttribute('pattern')) new jsFilter().pattern(activeElem);
+ };
/*
* To make it active to listen changes of those error fields.
*/
- applyGlobalListener: function (element) {
+ this.applyGlobalListener = function (element) {
element.addEventListener('change', this.quickValidation, false);
- },
+ };
/*
* To perform quick validation to respond those fields.
*/
- quickValidation: function (event) {
+ this.quickValidation = function (event) {
// jsLogger.out('Quick', event);
var log = [];
var target = event.target;
- log = jsRuleSets.checkValidation(target, log);
+ // To check the validation of an element.
+ log = new jsRuleSets().checkValidation(target, log);
// jsLogger.out('Quick Out', log);
- validationResponse.process(log);
- },
+ new validationResponse().process(log);
+ };
/*
* Single step instance validator for Ajax form submissions.
*/
- validate: function () {
+ this.validate = function () {
// Initiate form Check.
return this.check();
- }
-};
+ };
+}
/**
* Common Filter instances.
*/
-var jsFilter = {
- checkStatus: function (elem) {
+function jsFilter() {
+ this.checkStatus = function (elem) {
var status;
status = true;
- if (false === jsValidator.forceFilter) {
+ if (false === new jsValidator().forceFilter) {
status = false;
if (true === elem.required) {
status = true;
}
}
return status;
- },
+ };
// Number elements filter listener.
- number: function (element) {
+ this.number = function (element) {
var status = this.checkStatus(element);
if (true === status) element.addEventListener('keypress', this.isNumberKey, false);
- },
+ };
/*
* String elements filter listener.
*/
- string: function (element) {
+ this.string = function (element) {
// Getting "data" attribute for actions.
var type = element.getAttribute('data-allow');
var current = this;
@@ -261,89 +267,129 @@ var jsFilter = {
if (true === status) element.addEventListener('keypress', current.isPatternValid, false);
break;
}
- },
+ };
/*
* Pattern based filter and listener.
*/
- pattern: function (element) {
+ this.pattern = function (element) {
var current = this;
var status = this.checkStatus(element);
if (true === status) element.addEventListener('keypress', current.isPatternValid, false);
- },
+ };
/*
* Email elements filter listener.
*/
- email: function (element) {
+ this.email = function (element) {
var status = this.checkStatus(element);
if (true === status) element.addEventListener('keypress', jsRuleSets.email, false);
- },
- file: function (element) {
+ };
+ this.file = function (element) {
var status = this.checkStatus(element);
if (true === status) element.addEventListener('change', jsRuleSets.file, false);
- },
+ };
/*
* Numeric with Limited elements filter listener.
*/
- limit: function (element) {
+ this.limit = function (element) {
var status = this.checkStatus(element);
- if (true === status) element.addEventListener('input', this.isInLimit, false);
- },
+ if (true === status) element.addEventListener('change', this.isInLimit, false);
+ };
/*
* Restrict element with it's limit.
*/
- isInLimit: function (event) {
+ this.isInLimit = function (event) {
+ // Load the element value.
var value = event.target.value;
+
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
+
+ // Getting target element.
+ var target = event.target;
+
+ // Final value to load back.
+ var final_value = value;
+
// Getting object from element.
var min = event.target.min;
var max = event.target.max;
- // Default values for Min and Max.
- if (!min) min = 1;
- if (!max) max = 31;
- // Forming pattern for Restriction.
- var regex = new RegExp('^[0-9]+$');
- // Validation with Code.
- var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
- //jsLogger.out('Limit', regex.test(key) + ' | min |' + min + ' | max | ' + max);
- //jsLogger.out('Regex', regex.test(key));
- // Return status of the Action.
- if (false === regex.test(key) || parseInt(value) > max || parseInt(value) < min) {
- event.preventDefault();
- }
- var num = +this.value; //converts value to a Number
- if (!this.value.length) return false; //allows empty field
- this.value = isNaN(num) ? min : num > max ? max : num < min ? min : num;
+ // Get max-length attribute from element.
+ var max_length = event.target.getAttribute('data-maxlength') ? event.target.getAttribute('data-maxlength') : 0;
+ max_length = parseInt(max_length);
+ var num = value;
- event.target.value = event.target.value.substring(0, event.target.value.length - 1);
- },
+ // if "max_length" is "0", then its don't have limit variables.
+ if (0 === max_length) {
+
+ // Default values for Min and Max.
+ if (!min) min = 1;
+ if (!max) max = 100;
+
+ // Forming pattern for Restriction.
+ var regex = new RegExp('^[0-9]+$');
+
+ // Validation with Code.
+ var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
+
+ // Return status of the Action.
+ if (false === regex.test(key) || parseInt(value) > max || parseInt(value) < min) {
+ event.preventDefault();
+ }
+
+ // Parse to INT.
+ num = parseInt(num, 10);
+
+ // // converts value to a Number.
+ if (isNaN(num)) {
+ target.value = "";
+ return;
+ }
+
+ // Check value is greater than "max", then replace "max".
+ if (parseInt(num) > max) final_value = max;
+
+ // Check value is greater than "min", then replace "min".
+ if (parseInt(num) < min) final_value = min;
+
+ } else {
+ //TODO: Min length later.
+ // Validate the length of the string.
+ if ((num.length > max_length) && 0 < max_length) {
+ // If length is more, then cutoff the remaining letters.
+ final_value = num.substr(0, max_length);
+ }
+ }
+
+ // Revert value back to an element.
+ this.value = final_value;
+ };
/*
* Only allow alpha([a-zA-Z]).
*/
- isAlpha: function (event) {
+ this.isAlpha = function (event) {
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
// Managing the Pattern.
- var status = pattern.validate(event, 'a-zA-Z');
+ var status = new pattern().validate(event, 'a-zA-Z');
// Return status of the Action.
if (false === status) event.preventDefault();
- },
+ };
/*
* Only allow alpha([a-zA-Z0-9]).
*/
- isAlphaNumeric: function (event) {
+ this.isAlphaNumeric = function (event) {
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
// Managing the Pattern.
- var status = pattern.validate(event, 'a-zA-Z0-9');
+ var status = new pattern().validate(event, 'a-zA-Z0-9');
// Return status of the Action.
if (false === status) event.preventDefault();
- },
+ };
/*
* To check password is valid or not.
*/
- isValidPassword: function (event) {
+ this.isValidPassword = function (event) {
// Prevent using "space".
var charCode = (event.which) ? event.which : event.keyCode;
// If event is "space" then prevent to enter.
@@ -354,25 +400,25 @@ var jsFilter = {
if (true === helper.isWindowAction(event)) return true;
// Managing the Pattern.
- var status = pattern.validate(event, 'a-zA-Z0-9');
+ var status = new pattern().validate(event, 'a-zA-Z0-9');
// Return status of the Action.
if (false === status) event.preventDefault();
- },
+ };
/*
* Only allow by pattern(ex. ^[a-zA-Z0-3@#$!_.]+$).
*/
- isPatternValid: function (event) {
+ this.isPatternValid = function (event) {
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
// Managing the Pattern.
- var status = pattern.validate(event, 'a-zA-Z0-4');
+ var status = new pattern().validate(event, 'a-zA-Z0-4');
// Return status of the Action.
if (false === status) event.preventDefault();
- },
+ };
/*
* Check is numeric or not.
*/
- isNumberKey: function (event) {
+ this.isNumberKey = function (event) {
// To check is this action is from "windows" action or not.
if (true === helper.isWindowAction(event)) return true;
// Validation with Code.
@@ -383,57 +429,58 @@ var jsFilter = {
} // Return status of the Action.
return true;
- }
-};
+ };
+}
+
/**
* To Update overall JsValidator Settings.
*/
-var jsSettings = {
+function jsSettings() {
// Common error message color for form validation.
- errorColor: false,
+ this.errorColor = false;
// Set common template for error message
- errorTemplate: false,
+ this.errorTemplate = false;
/*
* To Initiate the Configurations.
*/
- init: function (option) {
+ this.init = function (option) {
// To update error message color to global object.
this.errorColor = option.errorColor;
// To update error template to handle error message.
this.errorTemplate = option.errorTemplate;
// Return "this" object.
return this;
- },
+ };
/*
* General Log.
*/
- log: function () {
+ this.log = function () {
jsLogger.out(this.errorColor);
jsLogger.out(this.errorTemplate);
- }
-};
+ };
+}
/**
* To Perform all Form based Operations.
*/
-var jsForm = {
+function jsForm() {
// Form element.
- form: false,
+ this.form = false;
// Form ID.
- formCore: false,
+ this.formCore = false;
// Form element's inputs.
- input: false,
+ this.input = false;
// Form element's selects.
- select: false,
+ this.select = false;
// Form element's textAreas.
- textArea: false,
+ this.textArea = false;
// Form element's labels.
- label: false,
+ this.label = false;
// Perform Force Filter on Elements.
- forceFilter: false,
+ this.forceFilter = false;
/*
* To Initiating the "jsForm".
*/
- init: function (option) {
+ this.init = function (option) {
jsLogger.out('Form', option.form);
// Update Global Option.
this.options = option;
@@ -446,11 +493,11 @@ var jsForm = {
// To Filter Required Elements.
this.required();
return this;
- },
+ };
/*
* To Register Active Form to Global Object.
*/
- registerForm: function (form) {
+ this.registerForm = function (form) {
// validate and Update Log.
if (typeof form === 'undefined') jsLogger.out('Form Identification', 'Form Identification is Missing !');
// Form should not be an ID.
@@ -460,11 +507,11 @@ var jsForm = {
if (null === this.form) jsLogger.out('Status 503', 'Failed to Proceed !');
// Update Direct Form ID.
this.formCore = form;
- },
+ };
/*
* To Parse all Relative Form components.
*/
- parseForm: function (form) {
+ this.parseForm = function (form) {
if (form === null) return false;
// "Input" elements like "text, date, time..."
this.input = form.getElementsByTagName('input');
@@ -474,39 +521,40 @@ var jsForm = {
this.textArea = form.getElementsByTagName('textarea');
// "Label" element.
this.label = form.getElementsByTagName('label');
- },
+ };
/*
* To set fields are required.
*/
- required: function () {
+ this.required = function () {
// var jsField = new jsField().init(this.options);
var forceFilter = this.forceFilter;
+ var jsField_obj = new jsField();
// Filter all required "input" elements.
- this.input = jsField.required(this.input, forceFilter);
+ this.input = jsField_obj.required(this.input, forceFilter);
// Filter all required "select" elements.
- this.select = jsField.required(this.select, forceFilter);
+ this.select = jsField_obj.required(this.select, forceFilter);
// Filter all required "textArea" elements.
- this.textArea = jsField.required(this.textArea, forceFilter);
- },
+ this.textArea = jsField_obj.required(this.textArea, forceFilter);
+ };
/*
* General Log.
*/
- log: function () {
+ this.log = function () {
jsLogger.out('Form', this.form);
jsLogger.out('input', this.input);
jsLogger.out('select', this.select);
jsLogger.out('textarea', this.textArea);
jsLogger.out('labels', this.label);
- }
-};
+ };
+}
/**
* Perform Operations in Field level.
*/
-var jsField = {
+function jsField() {
/*
* Return all required elements list.
*/
- required: function (field, forceFilter) {
+ this.required = function (field, forceFilter) {
var requiredFieldsList = [];
// Looping fields to filter.
for (var i = 0; i < field.length; i++) {
@@ -518,38 +566,38 @@ var jsField = {
} // Return list of required elements.
return requiredFieldsList;
- }
-};
+ };
+}
/**
* List of Validation Rules.
*/
-var jsRuleSets = {
+function jsRuleSets() {
/*
* To start validation process.
*/
- checkValidation: function (activeElem, log) {
+ this.checkValidation = function (activeElem, log) {
//jsLogger.out('Active Elem', activeElem);
var validElem = true;
+ var jsRuleSets_obj = new jsRuleSets();
// To Generally checks, the field is empty or not.
- if (!jsRuleSets.isSet(activeElem)) {
+ if (!jsRuleSets_obj.isSet(activeElem)) {
log.push({
'el': activeElem,
'type': 'required',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
+ validElem = false;
}
// To Check the Value is less than minimum or not.
if (activeElem.min) {
- if (jsRuleSets.isSet(activeElem)) {
- if (!jsRuleSets.min(activeElem)) {
+ if (jsRuleSets_obj.isSet(activeElem)) {
+ if (!jsRuleSets_obj.min(activeElem)) {
log.push({
'el': activeElem,
'type': 'min',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
validElem = false;
}
}
@@ -557,14 +605,13 @@ var jsRuleSets = {
// To Check the Value is grater than max or not.
if (activeElem.max) {
- if (jsRuleSets.isSet(activeElem)) {
- if (!jsRuleSets.max(activeElem)) {
+ if (jsRuleSets_obj.isSet(activeElem)) {
+ if (!jsRuleSets_obj.max(activeElem)) {
log.push({
'el': activeElem,
'type': 'max',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
validElem = false;
}
}
@@ -572,14 +619,13 @@ var jsRuleSets = {
// To Check the Entered E-mail is Valid or Not.
if (activeElem.type == 'email') {
- if (jsRuleSets.isSet(activeElem)) {
- if (!jsRuleSets.email(activeElem)) {
+ if (jsRuleSets_obj.isSet(activeElem)) {
+ if (!jsRuleSets_obj.email(activeElem)) {
log.push({
'el': activeElem,
'type': 'email',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
validElem = false;
}
}
@@ -588,14 +634,13 @@ var jsRuleSets = {
// To Compare the Password is Same or Not with Re-Password.
// TODO: Implement Simplified Comparison.
if (activeElem.type == 'password') {
- if (jsRuleSets.isSet(activeElem)) {
- if (!jsRuleSets.compare(activeElem)) {
+ if (jsRuleSets_obj.isSet(activeElem)) {
+ if (!jsRuleSets_obj.compare(activeElem)) {
log.push({
'el': activeElem,
'type': 'password',
- 'id': activeElem.name + '_new1_1_1xv_resp'
+ 'id': activeElem.name + __err_id_suffix_rand_hash
});
- firstErrorHit = activeElem.name + '_new1_1_1xv_resp';
validElem = false;
}
}
@@ -604,26 +649,26 @@ var jsRuleSets = {
if (true === validElem) {
//jsLogger.out('Valid Elem', activeElem);
if (activeElem.name !== '') {
- var elem = document.getElementById(activeElem.name + '_new1_1_1xv_resp');
+ var elem = document.getElementById(activeElem.name + __err_id_suffix_rand_hash);
if (typeof (elem) !== 'undefined' && elem !== null) {
// Remove element to avoid un-necessary buffer.
elem.remove();
}
}
}
+
// If error occurred, then locate that error
- if (false !== firstErrorHit) {
- //helper.scrollToItem(firstErrorHit);
+ if (false !== validElem) {
+ //
}
- // }
- // Return overall log report of validation.
+ // Return overall log report of validation.
return log;
- },
+ }
/*
* To Check, whether the element have value or not.
*/
- isSet: function (elem) {
+ this.isSet = function (elem) {
// If field is not required, then return "true".
if (false === elem.required) return true;
var status = true;
@@ -631,11 +676,11 @@ var jsRuleSets = {
//TODO: Implement suitable solution for this.
if (value.length === 0 || value === '' || value === ' ' || value === '[]') status = false;
return status;
- },
+ };
/*
* To Check Element with Min Condition.
*/
- min: function (elem) {
+ this.min = function (elem) {
// If field is not required, then return "true".
if (false === elem.required) return true;
var status = true;
@@ -644,11 +689,11 @@ var jsRuleSets = {
//TODO: Implement suitable solution for this.
if (value.length < min && value.length != 0) status = false;
return status;
- },
+ };
/*
* To Check Element with Max Condition.
*/
- max: function (elem) {
+ this.max = function (elem) {
// If field is not required, then return "true".
if (false === elem.required) return true;
var status = true;
@@ -657,11 +702,11 @@ var jsRuleSets = {
//TODO: Implement suitable solution for this.
if (value.length > max && value.length != 0) status = false;
return status;
- },
+ };
/*
* To Check Element Email is Valid or Not.
*/
- email: function (elem) {
+ this.email = function (elem) {
// If field is not required, then return "true".
if (false === elem.required) return true;
var status = false;
@@ -677,8 +722,11 @@ var jsRuleSets = {
}
if (!email) status = false;
return status;
- },
- file: function (elem) {
+ };
+ /*
+ * To Check Element's file is valid or not.
+ */
+ this.file = function (elem) {
var list_to_allow = elem.target.getAttribute('data-extensions');
var target = elem.target;
var list_to_allow_array;
@@ -702,21 +750,21 @@ var jsRuleSets = {
return false;
}
return true;
- },
+ };
/*
* To Check Element Phone Value is Valid or Not.
*/
- phone: function (elem, pattern) {
+ this.phone = function (elem, pattern) {
// If field is not required, then return "true".
if (false === elem.required) return true;
var status = true;
if (elem.value === '') status = false;
return status;
- },
+ };
/*
* To Compare two Elements Values.
*/
- compare: function (elem1) {
+ this.compare = function (elem1) {
var status = false;
// If field is not required, then return "true".
if (false === elem1.required) status = true;
@@ -730,48 +778,52 @@ var jsRuleSets = {
var elem2 = document.getElementById(elem2_id);
if (elem1.value === elem2.value) status = true;
}
- //jsLogger.out('Compare Status', status);
+ // Hardly remove the error message.
+ // document.getElementById(elem1.name + __err_id_suffix_rand_hash).remove();
+ // document.getElementById(elem2.name + __err_id_suffix_rand_hash).remove();
+
return status;
- }
-};
+ };
+}
/**
* To Manage JsValidator Errors.
*/
-var jsFormError = {
+function jsFormError() {
// Global constant to specify, error happened or not.
- errorHit: false,
+ this.errorHit = false;
// Error Css.
- errorCss: false,
+ this.errorCss = false;
// Success Css.
- successCss: false,
+ this.successCss = false;
/*
* Initiate overall form error handler.
*/
- init: function () {
+ this.init = function () {
this.errorHit = false;
this.errorCss = 'border-color: red;border-radius: 5px;color: red;';
this.successCss = 'border-color: green;border-radius: 5px;color: green;';
- },
+ };
/*
* Form error log.
*/
- log: function () {
+ this.log = function () {
// jsLogger.out('Form Error Hit', this.errorHit);
- },
+ };
/*
* Form error style.
*/
- style: function (css) {
+ this.style = function (css) {
this.errorCss = css.error;
this.successCss = css.success;
- }
-};
+ };
+}
/**
* For manage overall logging with validator.
*/
var jsLogger = {
status: function () {
- return jsValidator.option.log
+ // return jsValidator.option.log;
+ return __status_log;
},
/*
* Simple log with "heading" and "message".
@@ -799,7 +851,7 @@ var jsLogger = {
}
};
/**
- * General Helping methods.
+ * General Helping methods.jsField_obj
*/
var helper = {
/*
@@ -825,18 +877,32 @@ var helper = {
/*
* To Scroll Up / Down to notify the item that have validation message.
*/
- scrollToError: function () {
+ scrollToError: function (validateResponse) {
var dummy_id = '__header_error_target_temp';
- var active_class = validationResponse.getClass();
+ var active_class = validateResponse.getClass();
+
+ if (false === active_class) {
+ jsLogger.out('Active Class Error', 'ACTIVE CLASS NOT DEFINED, GET :' + active_class);
+ return false;
+ }
+
if (0 === document.getElementsByClassName(active_class).length) return false;
// Getting current ID of the element.
var active_id = document.getElementsByClassName(active_class)[0].id;
- // Update first element with dummy indec ID.
+ // Update first element with dummy index ID.
document.getElementsByClassName(active_class)[0].setAttribute('id', dummy_id);
// Forming ID.
- var id = '#' + document.getElementsByClassName(active_class)[0].id;
+ var id = document.getElementsByClassName(active_class)[0].id;
+ // Retrieve the element name.
+ var elem_name = active_id.replace(__err_id_suffix_rand_hash, '');
+ // Taking active element to navigate.
+ var top = document.getElementsByName(elem_name)[0].offsetTop;
+ // Format as ID.
+ id = '#' + id;
// Navigate to ID.
- window.location.href = id;
+ // window.location.href = id;
+ // Scroll to error element as close as possible.
+ window.scroll(0, parseInt(top) - 15);
// Restore with actual ID.
document.getElementsByClassName(active_class)[0].setAttribute('id', active_id);
// Remove the navigated value.
@@ -870,11 +936,11 @@ var helper = {
/**
* Simple library for Pattern.
*/
-var pattern = {
+function pattern() {
/*
* To generate pattern from element attribute.
*/
- getDefault: function (event, originalPattern) {
+ this.getDefault = function (event, originalPattern) {
if (typeof originalPattern == 'undefined') originalPattern = '';
// Getting special characters list.
var allow_special = event.target.getAttribute('data-allowSpecial');
@@ -891,11 +957,11 @@ var pattern = {
defaultPattern = '^[' + originalPattern + allow_special + ']+$';
}
return defaultPattern;
- },
+ };
/*
* To validate event with the pattern.
*/
- validate: function (event, pattern) {
+ this.validate = function (event, pattern) {
// Managing the Pattern.
var defaultPattern = this.getDefault(event, pattern);
// Validate with special formed pattern.
@@ -903,17 +969,17 @@ var pattern = {
// Validation with Code.
var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
return regex.test(key);
- }
-};
+ };
+}
/**
* To Manage all kind of error response.
*/
-var validationResponse = {
- active_class: false,
+function validationResponse() {
+ this.active_class = false;
/*
* Initiating the Response handler.
*/
- init: function (errorList, option) {
+ this.init = function (errorList, option) {
this.errorMessage = option.message;
// Updating the class.
this.active_class = option.errorClass;
@@ -923,35 +989,38 @@ var validationResponse = {
this.select(errorList.select);
this.textArea(errorList.textArea);
- },
+ };
/*
* To handle the "input" element.
*/
- input: function (elem) {
+ this.input = function (elem) {
// Initiate process for Input.
this.process(elem);
- },
+ };
/*
* To handle the "select" element.
*/
- select: function (elem) {
+ this.select = function (elem) {
// Initiate process for Select.
this.process(elem);
- },
- getClass: function () {
+ };
+ /*
+ * To return active class for validation response style.
+ */
+ this.getClass = function () {
return this.active_class;
- },
+ };
/*
* To handle the "textArea" element.
*/
- textArea: function (elem) {
+ this.textArea = function (elem) {
// Initiate process for TextArea.
this.process(elem);
- },
+ };
/*
* To process all handlers.
*/
- process: function (elem) {
+ this.process = function (elem) {
// Process with initial response.
var elementDefaultResponse = '';
// Get active class for error response element
@@ -981,11 +1050,11 @@ var validationResponse = {
activeElem.el.parentNode.insertBefore(spanTag, activeElem.el.nextSibling);
}
}
- },
+ };
/*
* Perform template creation and update.
*/
- template: function (activeElem, errorType) {
+ this.template = function (activeElem, errorType) {
//jsLogger.out('error Type 0', errorType);
var errorIndex = '';
var activeError = '';
@@ -1014,13 +1083,13 @@ var validationResponse = {
elementDefaultResponse = activeError;
}
return elementDefaultResponse;
- },
+ };
/*
* Default error handling messages.
* If user not specify the messages,
* then it will be replaces.
*/
- default: function (errorType) {
+ this.default = function (errorType) {
var active_class = this.getClass();
var errorMessages = {
required: 'This field is required.',
@@ -1033,5 +1102,5 @@ var validationResponse = {
if (typeof errorType !== 'string') return false;
if (typeof errorMessages[errorType] === 'undefined') return false;
return errorMessages[errorType];
- }
-};
\ No newline at end of file
+ };
+}
\ No newline at end of file
diff --git a/src/js/formValidator.min.js b/src/js/formValidator.min.js
index 105edcd..9ae653b 100644
--- a/src/js/formValidator.min.js
+++ b/src/js/formValidator.min.js
@@ -1,10 +1,10 @@
/*!
- * JavaScript Validator Library v1.0
+ * JavaScript Validator Library v2.0
* To perform effective validation and filter with form elements.
*
* Author : Shankar Thiyagaraajan
* Email : shankarthiyagaraajan@gmail.com
- * Github : https://github.com/shankarThiyagaraajan
+ * GitHub : https://github.com/shankarThiyagaraajan
*
* Source
* https://github.com/global-source/javascript_form_validator
@@ -17,7 +17,43 @@
* Released under the MIT license
* https://github.com/global-source/javascript_form_validator/blob/master/LICENSE
*
- * Date: 2017-07-21
+ * Date: 2017-08-03
*/
-var firstErrorHit=!1,jsValidator={formData:!1,onlyFilter:!1,jsForm:!1,jsSettings:!1,jsFormError:!1,formErrorList:{},forceFilter:!1,initialLoad:!0,option:!1,onChange:!1,init:function(e){return jsLogger.table(e),this.option=e,this.onlyFilter=e.onlyFilter,this.onChange=e.onChange,"undefined"==typeof e.errorClass&&(e.errorClass="js-error-cop"),this.jsSettings=jsSettings.init(e),this.jsForm=jsForm.init(e),this.jsFormError=jsFormError.init(),this.forceFilter=e.forceFilter,this.check(),this.submitListener(this.jsForm.formCore,this),this},submitListener:function(e,t){(!1===this.onlyFilter||"undefined"==typeof this.onlyFilter)&&document.querySelector("#"+e).addEventListener("submit",function(e){!1===t.check()&&e.preventDefault()})},update:function(){var e=this.option;this.onlyFilter=e.onlyFilter,this.jsSettings=jsSettings.init(e),this.jsForm=jsForm.init(e),this.jsFormError=jsFormError.init()},check:function(){var e=!1,t=this.jsForm,r=this.formErrorList,i=[];return r.input=this.elemLoop("input",t.input),r.textArea=this.elemLoop("textArea",t.textArea),r.select=this.elemLoop("select",t.select),jsLogger.out("Error List",this.formErrorList),i.push({errorElem:r}),0===r.input.length&&0===r.textArea.length&&0===r.select.length&&(e=!0),0==this.initialLoad&&validationResponse.init(r,this.option),this.initialLoad=!1,helper.scrollToError(),e},elemLoop:function(e,t){var r=[];if(null===t||"undefined"==typeof t)return!1;t=t.reverse();for(var i in t)if(t[i]){var n=t[i];this.applyFilters(n),1==this.onChange&&this.applyGlobalListener(n),(!1===this.onlyFilter||"undefined"==typeof this.onlyFilter)&&(r=jsRuleSets.checkValidation(n,r))}return r},applyFilters:function(e){"number"==e.type&&jsFilter.number(e),"email"==e.type&&jsFilter.email(e),"file"==e.type&&jsFilter.file(e),e.getAttribute("data-allow")&&jsFilter.string(e),e.getAttribute("pattern")&&jsFilter.pattern(e)},applyGlobalListener:function(e){e.addEventListener("change",this.quickValidation,!1)},quickValidation:function(e){var t=[],r=e.target;t=jsRuleSets.checkValidation(r,t),validationResponse.process(t)},validate:function(){return this.check()}},jsFilter={checkStatus:function(e){var t;return t=!0,!1===jsValidator.forceFilter&&(t=!1,!0===e.required&&(t=!0)),t},number:function(e){var t=this.checkStatus(e);!0===t&&e.addEventListener("keypress",this.isNumberKey,!1)},string:function(e){var t=e.getAttribute("data-allow"),r=this,i=this.checkStatus(e);switch(t){case"onlyAlpha":!0===i&&e.addEventListener("keypress",r.isAlpha,!1);break;case"string":!0===i&&e.addEventListener("keypress",r.isAlphaNumeric,!1);break;default:!0===i&&e.addEventListener("keypress",r.isPatternValid,!1)}},pattern:function(e){var t=this,r=this.checkStatus(e);!0===r&&e.addEventListener("keypress",t.isPatternValid,!1)},email:function(e){var t=this.checkStatus(e);!0===t&&e.addEventListener("keypress",jsRuleSets.email,!1)},file:function(e){var t=this.checkStatus(e);!0===t&&e.addEventListener("change",jsRuleSets.file,!1)},limit:function(e){var t=this.checkStatus(e);!0===t&&e.addEventListener("input",this.isInLimit,!1)},isInLimit:function(e){var t=e.target.value;if(!0===helper.isWindowAction(e))return!0;var r=e.target.min,i=e.target.max;r||(r=1),i||(i=31);var n=new RegExp("^[0-9]+$"),s=String.fromCharCode(e.charCode?e.charCode:e.which);(!1===n.test(s)||parseInt(t)>i||parseInt(t)i?i:r>o?r:o,void(e.target.value=e.target.value.substring(0,e.target.value.length-1))):!1},isAlpha:function(e){if(!0===helper.isWindowAction(e))return!0;var t=pattern.validate(e,"a-zA-Z");!1===t&&e.preventDefault()},isAlphaNumeric:function(e){if(!0===helper.isWindowAction(e))return!0;var t=pattern.validate(e,"a-zA-Z0-9");!1===t&&e.preventDefault()},isValidPassword:function(e){var t=e.which?e.which:e.keyCode;if(32===t)return e.preventDefault(),!1;if(!0===helper.isWindowAction(e))return!0;var r=pattern.validate(e,"a-zA-Z0-9");!1===r&&e.preventDefault()},isPatternValid:function(e){if(!0===helper.isWindowAction(e))return!0;var t=pattern.validate(e,"a-zA-Z0-4");!1===t&&e.preventDefault()},isNumberKey:function(e){if(!0===helper.isWindowAction(e))return!0;var t=e.which?e.which:e.keyCode;return 46===t||t>31&&(48>t||t>57)?(e.preventDefault(),!1):!0}},jsSettings={errorColor:!1,errorTemplate:!1,init:function(e){return this.errorColor=e.errorColor,this.errorTemplate=e.errorTemplate,this},log:function(){jsLogger.out(this.errorColor),jsLogger.out(this.errorTemplate)}},jsForm={form:!1,formCore:!1,input:!1,select:!1,textArea:!1,label:!1,forceFilter:!1,init:function(e){return jsLogger.out("Form",e.form),this.options=e,this.forceFilter=e.forceFilter,this.registerForm(e.form),this.parseForm(this.form),this.required(),this},registerForm:function(e){return"undefined"==typeof e&&jsLogger.out("Form Identification","Form Identification is Missing !"),null===e?!1:(this.form=document.getElementById(e),null===this.form&&jsLogger.out("Status 503","Failed to Proceed !"),void(this.formCore=e))},parseForm:function(e){return null===e?!1:(this.input=e.getElementsByTagName("input"),this.select=e.getElementsByTagName("select"),this.textArea=e.getElementsByTagName("textarea"),void(this.label=e.getElementsByTagName("label")))},required:function(){var e=this.forceFilter;this.input=jsField.required(this.input,e),this.select=jsField.required(this.select,e),this.textArea=jsField.required(this.textArea,e)},log:function(){jsLogger.out("Form",this.form),jsLogger.out("input",this.input),jsLogger.out("select",this.select),jsLogger.out("textarea",this.textArea),jsLogger.out("labels",this.label)}},jsField={required:function(e,t){for(var r=[],i=0;ii&&0!=r.length&&(t=!1),t},email:function(e){if(!1===e.required)return!0;var t=!1,r=e.value;return"undefined"==typeof r?!1:(r=r.toString(),/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(r)&&(t=!0),r||(t=!1),t)},file:function(e){var t,r,i=e.target.getAttribute("data-extensions"),n=e.target;if(""===i)return!0;t=-1===i.indexOf(",")?[i]:i.split(",");var s=n.value;return s=s.toLowerCase(),r=new RegExp("("+t.join("|").replace(/\./g,"\\.")+")$").test(s),!1===r?(alert('Allowed file types are "'+i+'" !'),e.target.value="",!1):!0},phone:function(e,t){if(!1===e.required)return!0;var r=!0;return""===e.value&&(r=!1),r},compare:function(e){var t=!1;!1===e.required&&(t=!0);var r=e.getAttribute("data-check");if(("undefined"==typeof r||null==r)&&(t=!1),null===r&&(r=e.getAttribute("data-parent")),null===r)t=!1;else{r=r.toString();var i=document.getElementById(r);e.value===i.value&&(t=!0)}return t}},jsFormError={errorHit:!1,errorCss:!1,successCss:!1,init:function(){this.errorHit=!1,this.errorCss="border-color: red;border-radius: 5px;color: red;",this.successCss="border-color: green;border-radius: 5px;color: green;"},log:function(){},style:function(e){this.errorCss=e.error,this.successCss=e.success}},jsLogger={out:function(e,t){console.log("======"+e+"======"),console.log(t),console.log("------------------------")},bulk:function(e){console.log(e)},table:function(e){console.table(e)}},helper={isWindowAction:function(e){var t=e||window.event,r=t.shiftKey||t.which;return 9===r||0===r||8===r||32===r||13===r||8===r||r>=35&&40>=r?!0:(r=String.fromCharCode(r),0===r.length?!0:!1)},scrollToError:function(){var e=validationResponse.getClass();if(0===document.getElementsByClassName(e).length)return!1;document.getElementsByClassName(e)[0].setAttribute("id","__header_error_target_temp");var t="#"+document.getElementsByClassName(e)[0].id;window.location.href=t,document.getElementsByClassName(e)[0].removeAttribute("id"),this.removeHash(t)},scrollToItem:function(e){var t=e;-1===t.indexOf("#")&&(t="#"+t),window.location.href=t,this.removeHash(t)},removeHash:function(e){var t=window.location.href;t=t.replace(e,""),window.history.pushState("","Title",t)}},pattern={getDefault:function(e,t){"undefined"==typeof t&&(t="");var r=e.target.getAttribute("data-allowSpecial"),i=e.target.pattern;console.log(i.length);var n;return r||null!==r||(r=""),r=r.toString(),n=""!==i&&i.length>0&&null!==i?i:"^["+t+r+"]+$"},validate:function(e,t){var r=this.getDefault(e,t),i=new RegExp(r),n=String.fromCharCode(e.charCode?e.charCode:e.which);return i.test(n)}},validationResponse={active_class:!1,init:function(e,t){this.errorMessage=t.message,this.active_class=t.errorClass,this.input(e.input),this.select(e.select),this.textArea(e.textArea)},input:function(e){this.process(e)},select:function(e){this.process(e)},getClass:function(){return this.active_class},textArea:function(e){this.process(e)},process:function(e){var t="",r=this.getClass();for(var i in e)if(e[i].el&&!0===e[i].el.required){var n=e[i],s=e[i].type;t=this.template(n,s);var o=document.getElementById(n.id);"undefined"==typeof o||"undefined"===o||null===o?(o=document.createElement("span"),o.setAttribute("id",n.id),o.setAttribute("class",r),o.innerHTML=t):o.innerHTML=t,n.el.parentNode.insertBefore(o,n.el.nextSibling)}},template:function(e,t){var r="",i="",n=e.el.getAttribute("data-message");return("undefined"==typeof n||""===n||null===n)&&("undefined"!=typeof this.errorMessage&&"undefined"!=typeof this.errorMessage[t]?(t=this.errorMessage[t],e.el.getAttribute("data-message"),t&&(i=t,("min"==e.type||"max"==e.type)&&("min"==e.type&&(r=e.el.min),"max"==e.type&&(r=e.el.max),i=i.replace("[INDEX]",r)))):i=this["default"](t),n=i),n},"default":function(e){var t=this.getClass(),r={required:'This field is required.',min:'This field length is too low.',max:'This field length is exceeds the limit.',password:'Password does not match.',email:'Email is not valid.',file:'This file is not allowed.'};return"string"!=typeof e?!1:"undefined"==typeof r[e]?!1:r[e]}};
\ No newline at end of file
+var __err_id_suffix_rand_hash='_new1_1_1xv_resp';var __status_log=!1;function jsValidator(){this.formData=!1;this.onlyFilter=!1;this.jsForm=!1;this.jsSettings=!1;this.jsFormError=!1;this.formErrorList={};this.forceFilter=!1;this.initialLoad=!0;this.option=!1;this.onChange=!1;this.validateResponse=!1;this.init=function(option){__status_log=option.log;this.option=option;jsLogger.table(option);this.onlyFilter=option.onlyFilter;this.onChange=option.onChange;if('undefined'===typeof option.errorClass)option.errorClass='js-error-cop';this.validateResponse=new validationResponse();this.jsSettings=new jsSettings().init(option);this.jsForm=new jsForm().init(option);this.jsFormError=new jsFormError().init();this.forceFilter=option.forceFilter;this.check();this.submitListener(this.jsForm.formCore,this);return this};this.submitListener=function(formID,obj){if(!1===this.onlyFilter||typeof(this.onlyFilter)==='undefined'){document.querySelector('#'+formID).addEventListener('submit',function(e){if(!1===obj.check()){e.preventDefault()}})}};this.update=function(){var option=this.option;this.onlyFilter=option.onlyFilter;this.jsSettings=new jsSettings().init(option);this.jsForm=new jsForm().init(option);this.jsFormError=new jsFormError().init()};this.check=function(){var status=!1;var jsFormObj=this.jsForm;var errorList=this.formErrorList;var option=[];errorList.input=this.elemLoop('input',jsFormObj.input);errorList.textArea=this.elemLoop('textArea',jsFormObj.textArea);errorList.select=this.elemLoop('select',jsFormObj.select);jsLogger.out('Error List',this.formErrorList);option.push({'errorElem':errorList});if(errorList.input.length===0){if(errorList.textArea.length===0){if(errorList.select.length===0){status=!0}}}
+ if(!1==this.initialLoad)this.validateResponse.init(errorList,this.option);this.initialLoad=!1;helper.scrollToError(this.validateResponse);return status};this.elemLoop=function(index,formElem){var log=[];if(formElem===null||typeof formElem==='undefined')return!1;formElem=formElem.reverse();for(var i in formElem){if(formElem[i]){var activeElem=formElem[i];this.applyFilters(activeElem);if(!0==this.onChange){this.applyGlobalListener(activeElem)}
+ if(!1===this.onlyFilter||typeof(this.onlyFilter)==='undefined'){log=new jsRuleSets().checkValidation(activeElem,log)}}}
+ return log};this.applyFilters=function(activeElem){if(activeElem.type=='number')new jsFilter().number(activeElem);if(activeElem.type=='email')new jsFilter().email(activeElem);if(''!==activeElem.min||''!==activeElem.max||activeElem.getAttribute('data-maxlength')||-1!==activeElem.maxLength)new jsFilter().limit(activeElem);if(activeElem.type=='file')new jsFilter().file(activeElem);if(activeElem.getAttribute('data-allow'))new jsFilter().string(activeElem);if(activeElem.getAttribute('pattern'))new jsFilter().pattern(activeElem)};this.applyGlobalListener=function(element){element.addEventListener('change',this.quickValidation,!1)};this.quickValidation=function(event){var log=[];var target=event.target;log=new jsRuleSets().checkValidation(target,log);new validationResponse().process(log)};this.validate=function(){return this.check()}}
+function jsFilter(){this.checkStatus=function(elem){var status;status=!0;if(!1===new jsValidator().forceFilter){status=!1;if(!0===elem.required){status=!0}}
+ return status};this.number=function(element){var status=this.checkStatus(element);if(!0===status)element.addEventListener('keypress',this.isNumberKey,!1)};this.string=function(element){var type=element.getAttribute('data-allow');var current=this;var status=this.checkStatus(element);switch(type){case 'onlyAlpha':if(!0===status)element.addEventListener('keypress',current.isAlpha,!1);break;case 'string':if(!0===status)element.addEventListener('keypress',current.isAlphaNumeric,!1);break;default:if(!0===status)element.addEventListener('keypress',current.isPatternValid,!1);break}};this.pattern=function(element){var current=this;var status=this.checkStatus(element);if(!0===status)element.addEventListener('keypress',current.isPatternValid,!1)};this.email=function(element){var status=this.checkStatus(element);if(!0===status)element.addEventListener('keypress',jsRuleSets.email,!1)};this.file=function(element){var status=this.checkStatus(element);if(!0===status)element.addEventListener('change',jsRuleSets.file,!1)};this.limit=function(element){var status=this.checkStatus(element);if(!0===status)element.addEventListener('change',this.isInLimit,!1)};this.isInLimit=function(event){var value=event.target.value;if(!0===helper.isWindowAction(event))return!0;var target=event.target;var final_value=value;var min=event.target.min;var max=event.target.max;var max_length=event.target.getAttribute('data-maxlength')?event.target.getAttribute('data-maxlength'):0;max_length=parseInt(max_length);var num=value;if(0===max_length){if(!min)min=1;if(!max)max=100;var regex=new RegExp('^[0-9]+$');var key=String.fromCharCode(!event.charCode?event.which:event.charCode);if(!1===regex.test(key)||parseInt(value)>max||parseInt(value)max)final_value=max;if(parseInt(num)max_length)&&031&&(charCode<48||charCode>57)){event.preventDefault();return!1}
+ return!0}}
+function jsSettings(){this.errorColor=!1;this.errorTemplate=!1;this.init=function(option){this.errorColor=option.errorColor;this.errorTemplate=option.errorTemplate;return this};this.log=function(){jsLogger.out(this.errorColor);jsLogger.out(this.errorTemplate)}}
+function jsForm(){this.form=!1;this.formCore=!1;this.input=!1;this.select=!1;this.textArea=!1;this.label=!1;this.forceFilter=!1;this.init=function(option){jsLogger.out('Form',option.form);this.options=option;this.forceFilter=option.forceFilter;this.registerForm(option.form);this.parseForm(this.form);this.required();return this};this.registerForm=function(form){if(typeof form==='undefined')jsLogger.out('Form Identification','Form Identification is Missing !');if(null===form)return!1;this.form=document.getElementById(form);if(null===this.form)jsLogger.out('Status 503','Failed to Proceed !');this.formCore=form};this.parseForm=function(form){if(form===null)return!1;this.input=form.getElementsByTagName('input');this.select=form.getElementsByTagName('select');this.textArea=form.getElementsByTagName('textarea');this.label=form.getElementsByTagName('label')};this.required=function(){var forceFilter=this.forceFilter;var jsField_obj=new jsField();this.input=jsField_obj.required(this.input,forceFilter);this.select=jsField_obj.required(this.select,forceFilter);this.textArea=jsField_obj.required(this.textArea,forceFilter)};this.log=function(){jsLogger.out('Form',this.form);jsLogger.out('input',this.input);jsLogger.out('select',this.select);jsLogger.out('textarea',this.textArea);jsLogger.out('labels',this.label)}}
+function jsField(){this.required=function(field,forceFilter){var requiredFieldsList=[];for(var i=0;imax&&value.length!=0)status=!1;return status};this.email=function(elem){if(!1===elem.required)return!0;var status=!1;var email=elem.value;if(typeof email==='undefined')return!1;email=email.toString();if(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)){status=!0}
+ if(!email)status=!1;return status};this.file=function(elem){var list_to_allow=elem.target.getAttribute('data-extensions');var target=elem.target;var list_to_allow_array;var file_response;if(''===list_to_allow)return!0;if(-1===list_to_allow.indexOf(',')){list_to_allow_array=[list_to_allow]}else{list_to_allow_array=list_to_allow.split(',')}
+ var fileName=target.value;fileName=fileName.toLowerCase();file_response=(new RegExp('('+list_to_allow_array.join('|').replace(/\./g,'\\.')+')$')).test(fileName);if(!1===file_response){alert('Allowed file types are "'+list_to_allow+'" !');elem.target.value='';return!1}
+ return!0};this.phone=function(elem,pattern){if(!1===elem.required)return!0;var status=!0;if(elem.value==='')status=!1;return status};this.compare=function(elem1){var status=!1;if(!1===elem1.required)status=!0;var elem2_id=elem1.getAttribute('data-check');if(typeof elem2_id=='undefined'||elem2_id==null)status=!1;if(elem2_id===null)elem2_id=elem1.getAttribute('data-parent');if(elem2_id===null){status=!1}else{elem2_id=elem2_id.toString();var elem2=document.getElementById(elem2_id);if(elem1.value===elem2.value)status=!0}
+ return status}}
+function jsFormError(){this.errorHit=!1;this.errorCss=!1;this.successCss=!1;this.init=function(){this.errorHit=!1;this.errorCss='border-color: red;border-radius: 5px;color: red;';this.successCss='border-color: green;border-radius: 5px;color: green;'};this.log=function(){};this.style=function(css){this.errorCss=css.error;this.successCss=css.success}}
+var jsLogger={status:function(){return __status_log},out:function(heading,message){if(!0!==this.status())return!1;console.log('======'+heading+'======');console.log(message);console.log('------------------------')},bulk:function(data){if(!0!==this.status())return!1;console.log(data)},table:function(data){if(!0!==this.status())return!1;console.table(data)}};var helper={isWindowAction:function(event){var theEvent=event||window.event;var key=theEvent.shiftKey||theEvent.which;if(key===9||key===0||key===8||key===32||key===13||key===8||(key>=35&&key<=40)){return!0}
+ key=String.fromCharCode(key);if(key.length===0)return!0;return!1},scrollToError:function(validateResponse){var dummy_id='__header_error_target_temp';var active_class=validateResponse.getClass();if(!1===active_class){jsLogger.out('Active Class Error','ACTIVE CLASS NOT DEFINED, GET :'+active_class);return!1}
+ if(0===document.getElementsByClassName(active_class).length)return!1;var active_id=document.getElementsByClassName(active_class)[0].id;document.getElementsByClassName(active_class)[0].setAttribute('id',dummy_id);var id=document.getElementsByClassName(active_class)[0].id;var elem_name=active_id.replace(__err_id_suffix_rand_hash,'');var top=document.getElementsByName(elem_name)[0].offsetTop;id='#'+id;window.scroll(0,parseInt(top)-15);document.getElementsByClassName(active_class)[0].setAttribute('id',active_id);this.removeHash(id)},scrollToItem:function(item){var hash=item;if(-1===hash.indexOf('#'))hash='#'+hash;window.location.href=hash;this.removeHash(hash)},removeHash:function(hash){var path=window.location.href;path=path.replace(hash,'');window.history.pushState('','Title',path)}};function pattern(){this.getDefault=function(event,originalPattern){if(typeof originalPattern=='undefined')originalPattern='';var allow_special=event.target.getAttribute('data-allowSpecial');var pattern=event.target.pattern;console.log(pattern.length);var defaultPattern;if(!allow_special&&allow_special===null)allow_special='';allow_special=allow_special.toString();if(pattern!==''&&pattern.length>0&&pattern!==null){defaultPattern=pattern}else{defaultPattern='^['+originalPattern+allow_special+']+$'}
+ return defaultPattern};this.validate=function(event,pattern){var defaultPattern=this.getDefault(event,pattern);var regex=new RegExp(defaultPattern);var key=String.fromCharCode(!event.charCode?event.which:event.charCode);return regex.test(key)}}
+function validationResponse(){this.active_class=!1;this.init=function(errorList,option){this.errorMessage=option.message;this.active_class=option.errorClass;this.input(errorList.input);this.select(errorList.select);this.textArea(errorList.textArea)};this.input=function(elem){this.process(elem)};this.select=function(elem){this.process(elem)};this.getClass=function(){return this.active_class};this.textArea=function(elem){this.process(elem)};this.process=function(elem){var elementDefaultResponse='';var active_class=this.getClass();for(var i in elem){if(elem[i].el&&!0===elem[i].el.required){var activeElem=elem[i];var errorType=elem[i].type;elementDefaultResponse=this.template(activeElem,errorType);var spanTag=document.getElementById(activeElem.id);if(typeof spanTag==='undefined'||spanTag==='undefined'||spanTag===null){spanTag=document.createElement('span');spanTag.setAttribute('id',activeElem.id);spanTag.setAttribute('class',active_class);spanTag.innerHTML=elementDefaultResponse}else{spanTag.innerHTML=elementDefaultResponse}
+ activeElem.el.parentNode.insertBefore(spanTag,activeElem.el.nextSibling)}}};this.template=function(activeElem,errorType){var errorIndex='';var activeError='';var elementDefaultResponse=activeElem.el.getAttribute('data-message');if(typeof elementDefaultResponse==='undefined'||elementDefaultResponse===''||elementDefaultResponse===null){if(typeof this.errorMessage!=='undefined'&&typeof this.errorMessage[errorType]!=='undefined'){errorType=this.errorMessage[errorType];if(errorType){activeError=errorType;if(activeElem.type=='min'||activeElem.type=='max'){if('min'==activeElem.type)errorIndex=activeElem.el.min;if('max'==activeElem.type)errorIndex=activeElem.el.max;activeError=activeError.replace('[INDEX]',errorIndex)}}}else{activeError=this.default(errorType)}
+ elementDefaultResponse=activeError}
+ return elementDefaultResponse};this.default=function(errorType){var active_class=this.getClass();var errorMessages={required:'This field is required.',min:'This field length is too low.',max:'This field length is exceeds the limit.',password:'Password does not match.',email:'Email is not valid.',file:'This file is not allowed.'};if(typeof errorType!=='string')return!1;if(typeof errorMessages[errorType]==='undefined')return!1;return errorMessages[errorType]}}
\ No newline at end of file
diff --git a/src/js/multi_formValidator.es6.js b/src/js/multi_formValidator.es6.js
deleted file mode 100644
index 4601cd7..0000000
--- a/src/js/multi_formValidator.es6.js
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*!
- * JavaScript Validator Library v1.0
- * To perform effective validation and filter with form elements.
- *
- * Author : Shankar Thiyagaraajan
- * Email : shankarthiyagaraajan@gmail.com
- * GitHub : https://github.com/shankarThiyagaraajan
- *
- * Source
- * https://github.com/global-source/javascript_form_validator
- *
- * Site
- * https://global-source.github.io/javascript_form_validator/
- *
- * Copyright 2017
- *
- * Released under the MIT license
- * https://github.com/global-source/javascript_form_validator/blob/master/LICENSE
- *
- * Date: 2017-07-21
- */
-
-/*
- * For Managing overall Validation flow.
- */
-let firstErrorHit = false;
-let __err_id_suffix_rand_hash = '_new1_1_1xv_resp';
-
-/**
- * Core Js Validator.
- */
-class jsValidator {
- constructor() {
- // Holding form element data.
- this.formData = false;
- // Switch complete validation and input filter.
- this.onlyFilter = false;
- // JS form.
- this.jsForm = false;
- // JS setting.
- this.jsSettings = false;
- // JS form error.
- this.jsFormError = false;
- // Overall error list.
- this.formErrorList = {};
- // To Filter non-required fields.
- this.forceFilter = false;
- // To Filter the First load.
- this.initialLoad = true;
- // Global options.
- this.option = false;
- // To apply global validator.
- this.onChange = false;
- this.validateResponse = false;
- }
-
- /*
- * Initiating the Validator.
- */
- init(option) {
- // To Update global options.
- this.option = option;
- jsLogger.table(option);
- // Updating the filter flag to global.
- this.onlyFilter = option.onlyFilter;
- // To Enable/Disable global validator.
- this.onChange = option.onChange;
- // Update default response "class".
- if ('undefined' === typeof option.errorClass) option.errorClass = 'js-error-cop';
- this.validateResponse = new validationResponse();
- // Update "jsSettings" to global object.
- this.jsSettings = new jsSettings().init(option);
- // Update "jsForm" to global object.
- this.jsForm = new jsForm().init(option);
- // Initiate form error setup.
- this.jsFormError = new jsFormError().init();
- // Update Force Field status.
- this.forceFilter = option.forceFilter;
- // To check the form elements.
- this.check();
- // To register the listener.
- this.submitListener(this.jsForm.formCore, this);
- // Send back "this".
- return this;
- };
-
- /*
- * To make listen on submit action of the form.
- */
- submitListener(formID, obj) {
- // To off submit listener, if only filter needed.
- if (false === this.onlyFilter || typeof (this.onlyFilter) === 'undefined') {
- // Initiate listener for form submission.
- document.querySelector('#' + formID).addEventListener('submit', function (e) {
- // To start form validations.
- // Check validation status.
- if (false === obj.check()) {
- //stop form from submitting, if validation fails
- e.preventDefault();
- }
- });
- }
- };
-
- /*
- * To Refresh the DOM and enable Dynamic-Elements to Access.
- */
- update() {
- let option = this.option;
- // Updating the filter flag to global.
- this.onlyFilter = option.onlyFilter;
- // Update "jsSettings" to global object.
- this.jsSettings = new jsSettings().init(option);
- // Update "jsForm" to global object.
- this.jsForm = new jsForm().init(option);
- // Initiate form error setup.
- this.jsFormError = new jsFormError().init();
- };
-
- /*
- * To checking all elements from registered form.
- */
- check() {
- let status = false;
- // Loading JS Form.
- let jsFormObj = this.jsForm;
- // Loading JS error list.
- let errorList = this.formErrorList;
- let option = [];
- // Looping the "input" elements for validation and filter implementation.
- errorList.input = this.elemLoop('input', jsFormObj.input);
- // Looping the "textArea" elements fro validation filter implementation.
- errorList.textArea = this.elemLoop('textArea', jsFormObj.textArea);
- // Looping the "select" elements fro validation filter implementation.
- errorList.select = this.elemLoop('select', jsFormObj.select);
- jsLogger.out('Error List', this.formErrorList);
- option.push({
- 'errorElem': errorList
- });
- // To Update global Validation Status.
- // If, Input elements have no errors.
- if (errorList.input.length === 0) {
- // If, Text Area elements have no errors.
- if (errorList.textArea.length === 0) {
- // If, Select elements have no errors.
- if (errorList.select.length === 0) {
- // If validation pass, then update "status" object.
- status = true;
- }
- }
- }
- if (false == this.initialLoad) this.validateResponse.init(errorList, this.option);
- this.initialLoad = false;
- helper.scrollToError(this.validateResponse);
- return status;
- };
-
- /*
- * To looping all elements for actions.
- */
- elemLoop(index, formElem) {
- // Initiate empty array for keep list of errors.
- let log = [];
- // Sanity check with "formElem".
- if (formElem === null || typeof formElem === 'undefined') return false;
- formElem = formElem.reverse();
- // Looping elements.
- for (let i in formElem) {
- if (formElem[i]) {
- // Switch to static letiable.
- let activeElem = formElem[i];
- // Apply filter to element.
- this.applyFilters(activeElem);
- // Register the DOM with live onChange validations.
- if (true == this.onChange) {
- this.applyGlobalListener(activeElem);
- }
- //jsLogger.out('Only Filter', this.onlyFilter);
- // If not only filter, then start validations.
- if (false === this.onlyFilter || typeof (this.onlyFilter) === 'undefined') {
- // Initiate validations and update to log.
- log = new jsRuleSets().checkValidation(activeElem, log);
- }
- }
- }
- // jsLogger.out('Log', log);
- return log;
- };
-
- /*
- * To apply filter to all relevant elements by it's attributes.
- */
- applyFilters(activeElem) {
- // Apply filter for Number elements.
- if (activeElem.type == 'number') new jsFilter().number(activeElem);
- // Apply filter for Email elements.
- if (activeElem.type == 'email') new jsFilter().email(activeElem);
- // Apply filter for Numeric elements.
- if (activeElem.min || activeElem.max || activeElem.getAttribute('data-maxlength') || activeElem.minLength || activeElem.maxLength) new jsFilter().limit(activeElem);
- // Apply filter File elements.
- if (activeElem.type == 'file') new jsFilter().file(activeElem);
- // Apply filter with string, alphaNumeric and pregMatch.
- if (activeElem.getAttribute('data-allow')) new jsFilter().string(activeElem);
- // Apply filter with pattern.
- if (activeElem.getAttribute('pattern')) new jsFilter().pattern(activeElem);
- };
-
- /*
- * To make it active to listen changes of those error fields.
- */
- applyGlobalListener(element) {
- element.addEventListener('change', this.quickValidation, false);
- };
-
- /*
- * To perform quick validation to respond those fields.
- */
- quickValidation(event) {
- // jsLogger.out('Quick', event);
- let log = [];
- let target = event.target;
- // To check the validation of an element.
- log = new jsRuleSets().checkValidation(target, log);
- // jsLogger.out('Quick Out', log);
- new validationResponse().process(log);
- };
-
- /*
- * Single step instance validator for Ajax form submissions.
- */
- validate() {
- // Initiate form Check.
- return this.check();
- };
-}
-/**
- * Common Filter instances.
- */
-class jsFilter {
- checkStatus(elem) {
- let status;
- status = true;
- if (false === new jsValidator().forceFilter) {
- status = false;
- if (true === elem.required) {
- status = true;
- }
- }
- return status;
- };
-
- // Number elements filter listener.
- number(element) {
- let status = this.checkStatus(element);
- if (true === status) element.addEventListener('keypress', this.isNumberKey, false);
- };
-
- /*
- * String elements filter listener.
- */
- string(element) {
- // Getting "data" attribute for actions.
- let type = element.getAttribute('data-allow');
- let current = this;
- let status = this.checkStatus(element);
-
- // Switching actions.
- switch (type) {
- // Allow only alphabets [a-zA-Z] not [0-9] and special characters.
- case 'onlyAlpha':
- if (true === status) element.addEventListener('keypress', current.isAlpha, false);
- break;
- // Allow only alpha Numeric [a-zA-Z0-9] not special characters.
- case 'string':
- if (true === status) element.addEventListener('keypress', current.isAlphaNumeric, false);
- break;
- // Allow based on the pattern given.
- default:
- if (true === status) element.addEventListener('keypress', current.isPatternValid, false);
- break;
- }
- };
-
- /*
- * Pattern based filter and listener.
- */
- pattern(element) {
- let current = this;
- let status = this.checkStatus(element);
- if (true === status) element.addEventListener('keypress', current.isPatternValid, false);
- };
-
- /*
- * Email elements filter listener.
- */
- email(element) {
- let status = this.checkStatus(element);
- if (true === status) element.addEventListener('keypress', jsRuleSets.email, false);
- };
-
- file(element) {
- let status = this.checkStatus(element);
- if (true === status) element.addEventListener('change', jsRuleSets.file, false);
- };
-
- /*
- * Numeric with Limited elements filter listener.
- */
- limit(element) {
- let current = this;
- let status = this.checkStatus(element);
- if (true === status) element.addEventListener('change', current.isInLimit, false);
- };
-
- /*
- * Restrict element with it's limit.
- */
- isInLimit(event) {
-
- // Load the element value.
- let value = event.target.value;
-
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
-
- // Getting target element.
- let target = event.target;
-
- // Final value to load back.
- let final_value = value;
-
- // Getting object from element.
- let min = event.target.min;
- let max = event.target.max;
-
- // Get max-length attribute from element.
- let max_length = event.target.getAttribute('data-maxlength') ? event.target.getAttribute('data-maxlength') : 0;
- max_length = parseInt(max_length);
- let num = value;
-
- // if "max_length" is "0", then its don't have limit letiables.
- if (0 === max_length) {
-
- // Default values for Min and Max.
- if (!min) min = 1;
- if (!max) max = 31;
-
- // Forming pattern for Restriction.
- let regex = new RegExp('^[0-9]+$');
-
- // Validation with Code.
- let key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
-
- // Return status of the Action.
- if (false === regex.test(key) || parseInt(value) > max || parseInt(value) < min) {
- event.preventDefault();
- }
-
- // Parse to INT.
- num = parseInt(num, 10);
-
- // // converts value to a Number.
- if (isNaN(num)) {
- target.value = "";
- return;
- }
-
- // Check value is greater than "max", then replace "max".
- if (parseInt(num) > max) final_value = max;
-
- // Check value is greater than "min", then replace "min".
- if (parseInt(num) < min) final_value = min;
-
- } else {
- //TODO: Min length later.
- // Validate the length of the string.
- if ((num.length > max_length) && 0 < max_length) {
- // If length is more, then cutoff the remaining letters.
- final_value = num.substr(0, max_length);
- }
- }
-
- // Revert value back to an element.
- this.value = final_value;
- };
-
- /*
- * Only allow alpha([a-zA-Z]).
- */
- isAlpha(event) {
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
- // Managing the Pattern.
- let status = new pattern().validate(event, 'a-zA-Z');
- // Return status of the Action.
- if (false === status) event.preventDefault();
- };
-
- /*
- * Only allow alpha([a-zA-Z0-9]).
- */
- isAlphaNumeric(event) {
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
- // Managing the Pattern.
- let status = new pattern().validate(event, 'a-zA-Z0-9');
- // Return status of the Action.
- if (false === status) event.preventDefault();
- };
-
- /*
- * To check password is valid or not.
- */
- isValidPassword(event) {
- // Prevent using "space".
- let charCode = (event.which) ? event.which : event.keyCode;
- // If event is "space" then prevent to enter.
- if (charCode === 32) {
- event.preventDefault();
- return false;
- } // To check is this action is from "windows" action or not.
-
- if (true === helper.isWindowAction(event)) return true;
- // Managing the Pattern.
- let status = new pattern().validate(event, 'a-zA-Z0-9');
- // Return status of the Action.
- if (false === status) event.preventDefault();
- };
-
- /*
- * Only allow by pattern(ex. ^[a-zA-Z0-3@#$!_.]+$).
- */
- isPatternValid(event) {
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
- // Managing the Pattern.
- let status = new pattern().validate(event, 'a-zA-Z0-4');
- // Return status of the Action.
- if (false === status) event.preventDefault();
- };
-
- /*
- * Check is numeric or not.
- */
- isNumberKey(event) {
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
- // Validation with Code.
- let charCode = (event.which) ? event.which : event.keyCode;
- if (charCode === 46 || charCode > 31 && (charCode < 48 || charCode > 57)) {
- event.preventDefault();
- return false;
- } // Return status of the Action.
-
- return true;
- };
-}
-
-/**
- * To Update overall JsValidator Settings.
- */
-class jsSettings {
- constructor() {
- // Common error message color for form validation.
- this.errorColor = false;
- // Set common template for error message
- this.errorTemplate = false;
- }
-
- /*
- * To Initiate the Configurations.
- */
- init(option) {
- // To update error message color to global object.
- this.errorColor = option.errorColor;
- // To update error template to handle error message.
- this.errorTemplate = option.errorTemplate;
- // Return "this" object.
- return this;
- };
-
- /*
- * General Log.
- */
- log() {
- jsLogger.out(this.errorColor);
- jsLogger.out(this.errorTemplate);
- };
-}
-/**
- * To Perform all Form based Operations.
- */
-class jsForm {
- constructor() {
- // Form element.
- this.form = false;
- // Form ID.
- this.formCore = false;
- // Form element's inputs.
- this.input = false;
- // Form element's selects.
- this.select = false;
- // Form element's textAreas.
- this.textArea = false;
- // Form element's labels.
- this.label = false;
- // Perform Force Filter on Elements.
- this.forceFilter = false;
- }
-
- /*
- * To Initiating the "jsForm".
- */
- init(option) {
- jsLogger.out('Form', option.form);
- // Update Global Option.
- this.options = option;
- // Enable/Disable Force Filter.
- this.forceFilter = option.forceFilter;
- // To Register Form.
- this.registerForm(option.form);
- // To Parsing the Form.
- this.parseForm(this.form);
- // To Filter Required Elements.
- this.required();
- return this;
- };
-
- /*
- * To Register Active Form to Global Object.
- */
- registerForm(form) {
- // validate and Update Log.
- if (typeof form === 'undefined') jsLogger.out('Form Identification', 'Form Identification is Missing !');
- // Form should not be an ID.
- if (null === form) return false;
- // Fetch Form element from Document.
- this.form = document.getElementById(form);
- if (null === this.form) jsLogger.out('Status 503', 'Failed to Proceed !');
- // Update Direct Form ID.
- this.formCore = form;
- };
-
- /*
- * To Parse all Relative Form components.
- */
- parseForm(form) {
- if (form === null) return false;
- // "Input" elements like "text, date, time..."
- this.input = form.getElementsByTagName('input');
- // "Select" element.
- this.select = form.getElementsByTagName('select');
- // "TextArea" element.
- this.textArea = form.getElementsByTagName('textarea');
- // "Label" element.
- this.label = form.getElementsByTagName('label');
- };
-
- /*
- * To set fields are required.
- */
- required() {
- // let jsField = new jsField().init(this.options);
- let forceFilter = this.forceFilter;
- let jsField_obj = new jsField();
- // Filter all required "input" elements.
- this.input = jsField_obj.required(this.input, forceFilter);
- // Filter all required "select" elements.
- this.select = jsField_obj.required(this.select, forceFilter);
- // Filter all required "textArea" elements.
- this.textArea = jsField_obj.required(this.textArea, forceFilter);
- };
-
- /*
- * General Log.
- */
- log() {
- jsLogger.out('Form', this.form);
- jsLogger.out('input', this.input);
- jsLogger.out('select', this.select);
- jsLogger.out('textarea', this.textArea);
- jsLogger.out('labels', this.label);
- };
-}
-/**
- * Perform Operations in Field level.
- */
-class jsField {
- /*
- * Return all required elements list.
- */
- required(field, forceFilter) {
- let requiredFieldsList = [];
- // Looping fields to filter.
- for (let i = 0; i < field.length; i++) {
- // Check and push elements.
- if (field[i].required === true || true === forceFilter) {
- // Pushing to required elements list.
- requiredFieldsList.push(field[i]);
- }
- } // Return list of required elements.
-
- return requiredFieldsList;
- };
-}
-/**
- * List of Validation Rules.
- */
-class jsRuleSets {
- /*
- * To start validation process.
- */
- checkValidation(activeElem, log) {
- //jsLogger.out('Active Elem', activeElem);
- let validElem = true;
- let jsRuleSets_obj = new jsRuleSets();
- // To Generally checks, the field is empty or not.
- if (!jsRuleSets_obj.isSet(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'required',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- }
-
- // To Check the Value is less than minimum or not.
- if (activeElem.min) {
- if (jsRuleSets_obj.isSet(activeElem)) {
- if (!jsRuleSets_obj.min(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'min',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- validElem = false;
- }
- }
- }
-
- // To Check the Value is grater than max or not.
- if (activeElem.max) {
- if (jsRuleSets_obj.isSet(activeElem)) {
- if (!jsRuleSets_obj.max(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'max',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- validElem = false;
- }
- }
- }
-
- // To Check the Entered E-mail is Valid or Not.
- if (activeElem.type == 'email') {
- if (jsRuleSets_obj.isSet(activeElem)) {
- if (!jsRuleSets_obj.email(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'email',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- validElem = false;
- }
- }
- }
-
- // To Compare the Password is Same or Not with Re-Password.
- // TODO: Implement Simplified Comparison.
- if (activeElem.type == 'password') {
- if (jsRuleSets_obj.isSet(activeElem)) {
- if (!jsRuleSets_obj.compare(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'password',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- validElem = false;
- }
- }
- } // If valid, then reset validation message.
-
- if (true === validElem) {
- //jsLogger.out('Valid Elem', activeElem);
- if (activeElem.name !== '') {
- let elem = document.getElementById(activeElem.name + __err_id_suffix_rand_hash);
- if (typeof (elem) !== 'undefined' && elem !== null) {
- // Remove element to avoid un-necessary buffer.
- elem.remove();
- }
- }
- }
- // If error occurred, then locate that error
- if (false !== firstErrorHit) {
- //helper.scrollToItem(firstErrorHit);
- }
- // }
- // Return overall log report of validation.
-
- return log;
- };
-
- /*
- * To Check, whether the element have value or not.
- */
- isSet(elem) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- let status = true;
- let value = elem.value;
- //TODO: Implement suitable solution for this.
- if (value.length === 0 || value === '' || value === ' ' || value === '[]') status = false;
- return status;
- };
-
- /*
- * To Check Element with Min Condition.
- */
- min(elem) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- let status = true;
- let value = elem.value;
- let min = elem.min;
- //TODO: Implement suitable solution for this.
- if (value.length < min && value.length != 0) status = false;
- return status;
- };
-
- /*
- * To Check Element with Max Condition.
- */
- max(elem) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- let status = true;
- let value = elem.value;
- let max = elem.max;
- //TODO: Implement suitable solution for this.
- if (value.length > max && value.length != 0) status = false;
- return status;
- };
-
- /*
- * To Check Element Email is Valid or Not.
- */
- email(elem) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- let status = false;
- let email = elem.value;
- if (typeof email === 'undefined') return false;
- // To Validate Email.
- // Convert to Native String Format.
- email = email.toString();
- // To Check it as String or Not.
- if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
- // Valid Email.
- status = true;
- }
- if (!email) status = false;
- return status;
- };
-
- file(elem) {
- let list_to_allow = elem.target.getAttribute('data-extensions');
- let target = elem.target;
- let list_to_allow_array;
- let file_response;
- if ('' === list_to_allow) return true;
- // Slit into array of extensions.
- if (-1 === list_to_allow.indexOf(',')) {
- list_to_allow_array = [list_to_allow];
- } else {
- list_to_allow_array = list_to_allow.split(',');
- }
- // Get file name.
- let fileName = target.value;
- // Convert to lower case for native validation.
- fileName = fileName.toLowerCase();
- file_response = (new RegExp('(' + list_to_allow_array.join('|').replace(/\./g, '\\.') + ')$')).test(fileName);
- if (false === file_response) {
- alert('Allowed file types are "' + list_to_allow + '" !');
- // Reset file type.
- elem.target.value = '';
- return false;
- }
- return true;
- };
-
- /*
- * To Check Element Phone Value is Valid or Not.
- */
- phone(elem, pattern) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- let status = true;
- if (elem.value === '') status = false;
- return status;
- };
-
- /*
- * To Compare two Elements Values.
- */
- compare(elem1) {
- let status = false;
- // If field is not required, then return "true".
- if (false === elem1.required) status = true;
- let elem2_id = elem1.getAttribute('data-check');
- if (typeof elem2_id == 'undefined' || elem2_id == null) status = false;
- if (elem2_id === null) elem2_id = elem1.getAttribute('data-parent');
- if (elem2_id === null) {
- status = false;
- } else {
- elem2_id = elem2_id.toString();
- let elem2 = document.getElementById(elem2_id);
- if (elem1.value === elem2.value) status = true;
- }
- //jsLogger.out('Compare Status', status);
- return status;
- };
-}
-/**
- * To Manage JsValidator Errors.
- */
-class jsFormError {
- constructor() {
- // Global constant to specify, error happened or not.
- this.errorHit = false;
- // Error Css.
- this.errorCss = false;
- // Success Css.
- this.successCss = false;
- }
-
- /*
- * Initiate overall form error handler.
- */
- init() {
- this.errorHit = false;
- this.errorCss = 'border-color: red;border-radius: 5px;color: red;';
- this.successCss = 'border-color: green;border-radius: 5px;color: green;';
- };
-
- /*
- * Form error log.
- */
- log() {
- // jsLogger.out('Form Error Hit', this.errorHit);
- };
-
- /*
- * Form error style.
- */
- style(css) {
- this.errorCss = css.error;
- this.successCss = css.success;
- };
-}
-/**
- * For manage overall logging with validator.
- */
-let jsLogger = {
- status: function () {
- // return jsValidator.option.log;
- return '[]';
- },
- /*
- * Simple log with "heading" and "message".
- */
- out: function (heading, message) {
-
- if (true !== this.status()) return false;
- console.log('======' + heading + '======');
- console.log(message);
- console.log('------------------------');
- },
- /*
- * For bulk data logging.
- */
- bulk: function (data) {
- if (true !== this.status()) return false;
- console.log(data);
- },
- /*
- * For log data with table.
- */
- table: function (data) {
- if (true !== this.status()) return false;
- console.table(data);
- }
-};
-/**
- * General Helping methods.jsField_obj
- */
-let helper = {
- /*
- * To check the keyboard action is window action or not.
- */
- isWindowAction: function (event) {
- // Getting the event to be triggered.
- let theEvent = event || window.event;
- // Getting the type of event or code.
- let key = theEvent.shiftKey || theEvent.which;
- // Check with list of code and ignore holding.
- // Tab, Space, Home, End, Up, Down, Left, Right...
- if (key === 9 || key === 0 || key === 8 || key === 32 || key === 13 || key === 8 || (key >= 35 && key <= 40)) {
- return true;
- } // If not in list then check return with corresponding data.
-
- key = String.fromCharCode(key);
- // Return also if length is 0.
- if (key.length === 0) return true;
- // Finally return "false" for general keys.
- return false;
- },
- /*
- * To Scroll Up / Down to notify the item that have validation message.
- */
- scrollToError: function (validateResponse) {
- let dummy_id = '__header_error_target_temp';
- let active_class = validateResponse.getClass();
-
- if (false === active_class) {
- jsLogger.out('Active Class Error', 'ACTIVE CLASS NOT DEFINED, GET :' + active_class);
- return false;
- }
-
- if (0 === document.getElementsByClassName(active_class).length) return false;
- // Getting current ID of the element.
- let active_id = document.getElementsByClassName(active_class)[0].id;
- // Update first element with dummy index ID.
- document.getElementsByClassName(active_class)[0].setAttribute('id', dummy_id);
- // Forming ID.
- let id = document.getElementsByClassName(active_class)[0].id;
- // Retrieve the element name.
- let elem_name = active_id.replace(__err_id_suffix_rand_hash, '');
- // Taking active element to navigate.
- let top = document.getElementsByName(elem_name)[0].offsetTop;
- // Format as ID.
- id = '#' + id;
- // Navigate to ID.
- // window.location.href = id;
- // Scroll to error element as close as possible.
- window.scroll(0, parseInt(top) - 15);
- // Restore with actual ID.
- document.getElementsByClassName(active_class)[0].setAttribute('id', active_id);
- // Remove the navigated value.
- this.removeHash(id);
- },
- /*
- * To Scroll Up / Down to notify the item that have validation message.
- */
- scrollToItem: function (item) {
- // Form hash value.
- let hash = item;
- // If "#" is missing, then add back to the ID.
- if (-1 === hash.indexOf('#')) hash = '#' + hash;
- // Navigate with the hash value.
- window.location.href = hash;
- // Remove the navigated value.
- this.removeHash(hash);
- },
- /*
- * To remove the hash value from the URL.
- */
- removeHash: function (hash) {
- // Getting the actual URL.
- let path = window.location.href;
- // Replacing the URL with specific hash value.
- path = path.replace(hash, '');
- // Update to url history.
- window.history.pushState('', 'Title', path);
- }
-};
-/**
- * Simple library for Pattern.
- */
-class pattern {
- /*
- * To generate pattern from element attribute.
- */
- getDefault(event, originalPattern) {
- if (typeof originalPattern == 'undefined') originalPattern = '';
- // Getting special characters list.
- let allow_special = event.target.getAttribute('data-allowSpecial');
- let pattern = event.target.pattern;
- console.log(pattern.length);
- let defaultPattern;
- // Set default values for special characters.
- if (!allow_special && allow_special === null) allow_special = '';
- // Format to string.
- allow_special = allow_special.toString();
- if (pattern !== '' && pattern.length > 0 && pattern !== null) {
- defaultPattern = pattern;
- } else {
- defaultPattern = '^[' + originalPattern + allow_special + ']+$';
- }
- return defaultPattern;
- };
-
- /*
- * To validate event with the pattern.
- */
- validate(event, pattern) {
- // Managing the Pattern.
- let defaultPattern = this.getDefault(event, pattern);
- // Validate with special formed pattern.
- let regex = new RegExp(defaultPattern);
- // Validation with Code.
- let key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
- return regex.test(key);
- };
-}
-/**
- * To Manage all kind of error response.
- */
-class validationResponse {
- constructor() {
- this.active_class = false;
- }
-
- /*
- * Initiating the Response handler.
- */
- init(errorList, option) {
- this.errorMessage = option.message;
- // Updating the class.
- this.active_class = option.errorClass;
- // let errorElements = option.errorElem;
- // jsLogger.out('Errors', errorList);
- this.input(errorList.input);
- this.select(errorList.select);
- this.textArea(errorList.textArea);
-
- };
-
- /*
- * To handle the "input" element.
- */
- input(elem) {
- // Initiate process for Input.
- this.process(elem);
- };
-
- /*
- * To handle the "select" element.
- */
- select(elem) {
- // Initiate process for Select.
- this.process(elem);
- };
-
- /*
- * To return active class for validation response style.
- */
- getClass() {
- return this.active_class;
- };
-
- /*
- * To handle the "textArea" element.
- */
- textArea(elem) {
- // Initiate process for TextArea.
- this.process(elem);
- };
-
- /*
- * To process all handlers.
- */
- process(elem) {
- // Process with initial response.
- let elementDefaultResponse = '';
- // Get active class for error response element
- let active_class = this.getClass();
- for (let i in elem) {
- // jsLogger.out('Element', document.getElementById(elem[i].id));
- if (elem[i].el && true === elem[i].el.required) {
- // Manage active element.
- let activeElem = elem[i];
- let errorType = elem[i].type;
- // Fetch from Element's direct message.
- elementDefaultResponse = this.template(activeElem, errorType);
- let spanTag = document.getElementById(activeElem.id);
- // jsLogger.out('Element Hit', errorType);
- // Create new response Message SPAN.
- if (typeof spanTag === 'undefined' || spanTag === 'undefined' || spanTag === null) {
- // jsLogger.out('Element Found', false);
- spanTag = document.createElement('span');
- spanTag.setAttribute('id', activeElem.id);
- spanTag.setAttribute('class', active_class);
- spanTag.innerHTML = elementDefaultResponse;
- } else {
- // Re-use Existing response Message SPAN.
- spanTag.innerHTML = elementDefaultResponse;
- }
- // Append HTML response to the Element.
- activeElem.el.parentNode.insertBefore(spanTag, activeElem.el.nextSibling);
- }
- }
- };
-
- /*
- * Perform template creation and update.
- */
- template(activeElem, errorType) {
- //jsLogger.out('error Type 0', errorType);
- let errorIndex = '';
- let activeError = '';
- // Getting error response message from elemnet.
- let elementDefaultResponse = activeElem.el.getAttribute('data-message');
- if (typeof elementDefaultResponse === 'undefined' || elementDefaultResponse === '' || elementDefaultResponse === null) {
- // Sanity check with error message object.
- if (typeof this.errorMessage !== 'undefined' && typeof this.errorMessage[errorType] !== 'undefined') {
- // Getting error type. [ex. Required, Min, Max...]
- errorType = this.errorMessage[errorType];
-
- // activeElem.el.getAttribute('data-message');
- if (errorType) {
- //jsLogger.out('errorType', errorType);
- activeError = errorType;
- // If error type is Min or Max, then it will proceed responsive.
- if (activeElem.type == 'min' || activeElem.type == 'max') {
- if ('min' == activeElem.type) errorIndex = activeElem.el.min;
- if ('max' == activeElem.type) errorIndex = activeElem.el.max;
- activeError = activeError.replace('[INDEX]', errorIndex);
- }
- }
- } else {
- activeError = this.default(errorType);
- }
- elementDefaultResponse = activeError;
- }
- return elementDefaultResponse;
- };
-
- /*
- * Default error handling messages.
- * If user not specify the messages,
- * then it will be replaces.
- */
- default(errorType) {
- let active_class = this.getClass();
- let errorMessages = {
- required: 'This field is required.',
- min: 'This field length is too low.',
- max: 'This field length is exceeds the limit.',
- password: 'Password does not match.',
- email: 'Email is not valid.',
- file: 'This file is not allowed.'
- };
- if (typeof errorType !== 'string') return false;
- if (typeof errorMessages[errorType] === 'undefined') return false;
- return errorMessages[errorType];
- };
-}
\ No newline at end of file
diff --git a/src/js/multi_formValidator.js b/src/js/multi_formValidator.js
deleted file mode 100644
index 0cfa1d9..0000000
--- a/src/js/multi_formValidator.js
+++ /dev/null
@@ -1,1105 +0,0 @@
-/*!
- * JavaScript Validator Library v1.0
- * To perform effective validation and filter with form elements.
- *
- * Author : Shankar Thiyagaraajan
- * Email : shankarthiyagaraajan@gmail.com
- * GitHub : https://github.com/shankarThiyagaraajan
- *
- * Source
- * https://github.com/global-source/javascript_form_validator
- *
- * Site
- * https://global-source.github.io/javascript_form_validator/
- *
- * Copyright 2017
- *
- * Released under the MIT license
- * https://github.com/global-source/javascript_form_validator/blob/master/LICENSE
- *
- * Date: 2017-07-21
- */
-
-/*
- * For Managing overall Validation flow.
- */
-var firstErrorHit = false;
-var __err_id_suffix_rand_hash = '_new1_1_1xv_resp';
-/**
- * Core Js Validator.
- */
-function jsValidator() {
- // Holding form element data.
- this.formData = false;
- // Switch complete validation and input filter.
- this.onlyFilter = false;
- // JS form.
- this.jsForm = false;
- // JS setting.
- this.jsSettings = false;
- // JS form error.
- this.jsFormError = false;
- // Overall error list.
- this.formErrorList = {};
- // To Filter non-required fields.
- this.forceFilter = false;
- // To Filter the First load.
- this.initialLoad = true;
- // Global options.
- this.option = false;
- // To apply global validator.
- this.onChange = false;
- this.validateResponse = false;
- /*
- * Initiating the Validator.
- */
- this.init = function (option) {
- // To Update global options.
- this.option = option;
- jsLogger.table(option);
- // Updating the filter flag to global.
- this.onlyFilter = option.onlyFilter;
- // To Enable/Disable global validator.
- this.onChange = option.onChange;
- // Update default response "class".
- if ('undefined' === typeof option.errorClass) option.errorClass = 'js-error-cop';
- this.validateResponse = new validationResponse();
- // Update "jsSettings" to global object.
- this.jsSettings = new jsSettings().init(option);
- // Update "jsForm" to global object.
- this.jsForm = new jsForm().init(option);
- // Initiate form error setup.
- this.jsFormError = new jsFormError().init();
- // Update Force Field status.
- this.forceFilter = option.forceFilter;
- // To check the form elements.
- this.check();
- // To register the listener.
- this.submitListener(this.jsForm.formCore, this);
- // Send back "this".
- return this;
- };
- /*
- * To make listen on submit action of the form.
- */
- this.submitListener = function (formID, obj) {
- // To off submit listener, if only filter needed.
- if (false === this.onlyFilter || typeof (this.onlyFilter) === 'undefined') {
- // Initiate listener for form submission.
- document.querySelector('#' + formID).addEventListener('submit', function (e) {
- // To start form validations.
- // Check validation status.
- if (false === obj.check()) {
- //stop form from submitting, if validation fails
- e.preventDefault();
- }
- });
- }
- };
- /*
- * To Refresh the DOM and enable Dynamic-Elements to Access.
- */
- this.update = function () {
- var option = this.option;
- // Updating the filter flag to global.
- this.onlyFilter = option.onlyFilter;
- // Update "jsSettings" to global object.
- this.jsSettings = new jsSettings().init(option);
- // Update "jsForm" to global object.
- this.jsForm = new jsForm().init(option);
- // Initiate form error setup.
- this.jsFormError = new jsFormError().init();
- };
- /*
- * To checking all elements from registered form.
- */
- this.check = function () {
- var status = false;
- // Loading JS Form.
- var jsFormObj = this.jsForm;
- // Loading JS error list.
- var errorList = this.formErrorList;
- var option = [];
- // Looping the "input" elements for validation and filter implementation.
- errorList.input = this.elemLoop('input', jsFormObj.input);
- // Looping the "textArea" elements fro validation filter implementation.
- errorList.textArea = this.elemLoop('textArea', jsFormObj.textArea);
- // Looping the "select" elements fro validation filter implementation.
- errorList.select = this.elemLoop('select', jsFormObj.select);
- jsLogger.out('Error List', this.formErrorList);
- option.push({
- 'errorElem': errorList
- });
- // To Update global Validation Status.
- // If, Input elements have no errors.
- if (errorList.input.length === 0) {
- // If, Text Area elements have no errors.
- if (errorList.textArea.length === 0) {
- // If, Select elements have no errors.
- if (errorList.select.length === 0) {
- // If validation pass, then update "status" object.
- status = true;
- }
- }
- }
- if (false == this.initialLoad) this.validateResponse.init(errorList, this.option);
- this.initialLoad = false;
- helper.scrollToError(this.validateResponse);
- return status;
- };
- /*
- * To looping all elements for actions.
- */
- this.elemLoop = function (index, formElem) {
- // Initiate empty array for keep list of errors.
- var log = [];
- // Sanity check with "formElem".
- if (formElem === null || typeof formElem === 'undefined') return false;
- formElem = formElem.reverse();
- // Looping elements.
- for (var i in formElem) {
- if (formElem[i]) {
- // Switch to static variable.
- var activeElem = formElem[i];
- // Apply filter to element.
- this.applyFilters(activeElem);
- // Register the DOM with live onChange validations.
- if (true == this.onChange) {
- this.applyGlobalListener(activeElem);
- }
- //jsLogger.out('Only Filter', this.onlyFilter);
- // If not only filter, then start validations.
- if (false === this.onlyFilter || typeof (this.onlyFilter) === 'undefined') {
- // Initiate validations and update to log.
- log = new jsRuleSets().checkValidation(activeElem, log);
- }
- }
- }
- // jsLogger.out('Log', log);
- return log;
- };
- /*
- * To apply filter to all relevant elements by it's attributes.
- */
- this.applyFilters = function (activeElem) {
- // Apply filter for Number elements.
- if (activeElem.type == 'number') new jsFilter().number(activeElem);
- // Apply filter for Email elements.
- if (activeElem.type == 'email') new jsFilter().email(activeElem);
- // Apply filter for Numeric elements.
- if (activeElem.min || activeElem.max || activeElem.getAttribute('data-maxlength') || activeElem.minLength || activeElem.maxLength) new jsFilter().limit(activeElem);
- // Apply filter File elements.
- if (activeElem.type == 'file') new jsFilter().file(activeElem);
- // Apply filter with string, alphaNumeric and pregMatch.
- if (activeElem.getAttribute('data-allow')) new jsFilter().string(activeElem);
- // Apply filter with pattern.
- if (activeElem.getAttribute('pattern')) new jsFilter().pattern(activeElem);
- };
- /*
- * To make it active to listen changes of those error fields.
- */
- this.applyGlobalListener = function (element) {
- element.addEventListener('change', this.quickValidation, false);
- };
- /*
- * To perform quick validation to respond those fields.
- */
- this.quickValidation = function (event) {
- // jsLogger.out('Quick', event);
- var log = [];
- var target = event.target;
- // To check the validation of an element.
- log = new jsRuleSets().checkValidation(target, log);
- // jsLogger.out('Quick Out', log);
- new validationResponse().process(log);
- };
- /*
- * Single step instance validator for Ajax form submissions.
- */
- this.validate = function () {
- // Initiate form Check.
- return this.check();
- };
-}
-/**
- * Common Filter instances.
- */
-function jsFilter() {
- this.checkStatus = function (elem) {
- var status;
- status = true;
- if (false === new jsValidator().forceFilter) {
- status = false;
- if (true === elem.required) {
- status = true;
- }
- }
- return status;
- };
- // Number elements filter listener.
- this.number = function (element) {
- var status = this.checkStatus(element);
- if (true === status) element.addEventListener('keypress', this.isNumberKey, false);
- };
- /*
- * String elements filter listener.
- */
- this.string = function (element) {
- // Getting "data" attribute for actions.
- var type = element.getAttribute('data-allow');
- var current = this;
- var status = this.checkStatus(element);
-
- // Switching actions.
- switch (type) {
- // Allow only alphabets [a-zA-Z] not [0-9] and special characters.
- case 'onlyAlpha':
- if (true === status) element.addEventListener('keypress', current.isAlpha, false);
- break;
- // Allow only alpha Numeric [a-zA-Z0-9] not special characters.
- case 'string':
- if (true === status) element.addEventListener('keypress', current.isAlphaNumeric, false);
- break;
- // Allow based on the pattern given.
- default:
- if (true === status) element.addEventListener('keypress', current.isPatternValid, false);
- break;
- }
- };
- /*
- * Pattern based filter and listener.
- */
- this.pattern = function (element) {
- var current = this;
- var status = this.checkStatus(element);
- if (true === status) element.addEventListener('keypress', current.isPatternValid, false);
- };
- /*
- * Email elements filter listener.
- */
- this.email = function (element) {
- var status = this.checkStatus(element);
- if (true === status) element.addEventListener('keypress', jsRuleSets.email, false);
- };
- this.file = function (element) {
- var status = this.checkStatus(element);
- if (true === status) element.addEventListener('change', jsRuleSets.file, false);
- };
- /*
- * Numeric with Limited elements filter listener.
- */
- this.limit = function (element) {
- var status = this.checkStatus(element);
- if (true === status) element.addEventListener('change', this.isInLimit, false);
- };
- /*
- * Restrict element with it's limit.
- */
- this.isInLimit = function (event) {
- // Load the element value.
- var value = event.target.value;
-
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
-
- // Getting target element.
- var target = event.target;
-
- // Final value to load back.
- var final_value = value;
-
- // Getting object from element.
- var min = event.target.min;
- var max = event.target.max;
-
- // Get max-length attribute from element.
- var max_length = event.target.getAttribute('data-maxlength') ? event.target.getAttribute('data-maxlength') : 0;
- max_length = parseInt(max_length);
- var num = value;
-
- // if "max_length" is "0", then its don't have limit variables.
- if (0 === max_length) {
-
- // Default values for Min and Max.
- if (!min) min = 1;
- if (!max) max = 31;
-
- // Forming pattern for Restriction.
- var regex = new RegExp('^[0-9]+$');
-
- // Validation with Code.
- var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
-
- // Return status of the Action.
- if (false === regex.test(key) || parseInt(value) > max || parseInt(value) < min) {
- event.preventDefault();
- }
-
- // Parse to INT.
- num = parseInt(num, 10);
-
- // // converts value to a Number.
- if (isNaN(num)) {
- target.value = "";
- return;
- }
-
- // Check value is greater than "max", then replace "max".
- if (parseInt(num) > max) final_value = max;
-
- // Check value is greater than "min", then replace "min".
- if (parseInt(num) < min) final_value = min;
-
- } else {
- //TODO: Min length later.
- // Validate the length of the string.
- if ((num.length > max_length) && 0 < max_length) {
- // If length is more, then cutoff the remaining letters.
- final_value = num.substr(0, max_length);
- }
- }
-
- // Revert value back to an element.
- this.value = final_value;
- };
- /*
- * Only allow alpha([a-zA-Z]).
- */
- this.isAlpha = function (event) {
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
- // Managing the Pattern.
- var status = new pattern().validate(event, 'a-zA-Z');
- // Return status of the Action.
- if (false === status) event.preventDefault();
- };
- /*
- * Only allow alpha([a-zA-Z0-9]).
- */
- this.isAlphaNumeric = function (event) {
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
- // Managing the Pattern.
- var status = new pattern().validate(event, 'a-zA-Z0-9');
- // Return status of the Action.
- if (false === status) event.preventDefault();
- };
- /*
- * To check password is valid or not.
- */
- this.isValidPassword = function (event) {
- // Prevent using "space".
- var charCode = (event.which) ? event.which : event.keyCode;
- // If event is "space" then prevent to enter.
- if (charCode === 32) {
- event.preventDefault();
- return false;
- } // To check is this action is from "windows" action or not.
-
- if (true === helper.isWindowAction(event)) return true;
- // Managing the Pattern.
- var status = new pattern().validate(event, 'a-zA-Z0-9');
- // Return status of the Action.
- if (false === status) event.preventDefault();
- };
- /*
- * Only allow by pattern(ex. ^[a-zA-Z0-3@#$!_.]+$).
- */
- this.isPatternValid = function (event) {
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
- // Managing the Pattern.
- var status = new pattern().validate(event, 'a-zA-Z0-4');
- // Return status of the Action.
- if (false === status) event.preventDefault();
- };
- /*
- * Check is numeric or not.
- */
- this.isNumberKey = function (event) {
- // To check is this action is from "windows" action or not.
- if (true === helper.isWindowAction(event)) return true;
- // Validation with Code.
- var charCode = (event.which) ? event.which : event.keyCode;
- if (charCode === 46 || charCode > 31 && (charCode < 48 || charCode > 57)) {
- event.preventDefault();
- return false;
- } // Return status of the Action.
-
- return true;
- };
-}
-
-/**
- * To Update overall JsValidator Settings.
- */
-function jsSettings() {
- // Common error message color for form validation.
- this.errorColor = false;
- // Set common template for error message
- this.errorTemplate = false;
- /*
- * To Initiate the Configurations.
- */
- this.init = function (option) {
- // To update error message color to global object.
- this.errorColor = option.errorColor;
- // To update error template to handle error message.
- this.errorTemplate = option.errorTemplate;
- // Return "this" object.
- return this;
- };
- /*
- * General Log.
- */
- this.log = function () {
- jsLogger.out(this.errorColor);
- jsLogger.out(this.errorTemplate);
- };
-}
-/**
- * To Perform all Form based Operations.
- */
-function jsForm() {
- // Form element.
- this.form = false;
- // Form ID.
- this.formCore = false;
- // Form element's inputs.
- this.input = false;
- // Form element's selects.
- this.select = false;
- // Form element's textAreas.
- this.textArea = false;
- // Form element's labels.
- this.label = false;
- // Perform Force Filter on Elements.
- this.forceFilter = false;
- /*
- * To Initiating the "jsForm".
- */
- this.init = function (option) {
- jsLogger.out('Form', option.form);
- // Update Global Option.
- this.options = option;
- // Enable/Disable Force Filter.
- this.forceFilter = option.forceFilter;
- // To Register Form.
- this.registerForm(option.form);
- // To Parsing the Form.
- this.parseForm(this.form);
- // To Filter Required Elements.
- this.required();
- return this;
- };
- /*
- * To Register Active Form to Global Object.
- */
- this.registerForm = function (form) {
- // validate and Update Log.
- if (typeof form === 'undefined') jsLogger.out('Form Identification', 'Form Identification is Missing !');
- // Form should not be an ID.
- if (null === form) return false;
- // Fetch Form element from Document.
- this.form = document.getElementById(form);
- if (null === this.form) jsLogger.out('Status 503', 'Failed to Proceed !');
- // Update Direct Form ID.
- this.formCore = form;
- };
- /*
- * To Parse all Relative Form components.
- */
- this.parseForm = function (form) {
- if (form === null) return false;
- // "Input" elements like "text, date, time..."
- this.input = form.getElementsByTagName('input');
- // "Select" element.
- this.select = form.getElementsByTagName('select');
- // "TextArea" element.
- this.textArea = form.getElementsByTagName('textarea');
- // "Label" element.
- this.label = form.getElementsByTagName('label');
- };
- /*
- * To set fields are required.
- */
- this.required = function () {
- // var jsField = new jsField().init(this.options);
- var forceFilter = this.forceFilter;
- var jsField_obj = new jsField();
- // Filter all required "input" elements.
- this.input = jsField_obj.required(this.input, forceFilter);
- // Filter all required "select" elements.
- this.select = jsField_obj.required(this.select, forceFilter);
- // Filter all required "textArea" elements.
- this.textArea = jsField_obj.required(this.textArea, forceFilter);
- };
- /*
- * General Log.
- */
- this.log = function () {
- jsLogger.out('Form', this.form);
- jsLogger.out('input', this.input);
- jsLogger.out('select', this.select);
- jsLogger.out('textarea', this.textArea);
- jsLogger.out('labels', this.label);
- };
-}
-/**
- * Perform Operations in Field level.
- */
-function jsField() {
- /*
- * Return all required elements list.
- */
- this.required = function (field, forceFilter) {
- var requiredFieldsList = [];
- // Looping fields to filter.
- for (var i = 0; i < field.length; i++) {
- // Check and push elements.
- if (field[i].required === true || true === forceFilter) {
- // Pushing to required elements list.
- requiredFieldsList.push(field[i]);
- }
- } // Return list of required elements.
-
- return requiredFieldsList;
- };
-}
-/**
- * List of Validation Rules.
- */
-function jsRuleSets() {
- /*
- * To start validation process.
- */
- this.checkValidation = function (activeElem, log) {
- //jsLogger.out('Active Elem', activeElem);
- var validElem = true;
- var jsRuleSets_obj = new jsRuleSets();
- // To Generally checks, the field is empty or not.
- if (!jsRuleSets_obj.isSet(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'required',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- }
-
- // To Check the Value is less than minimum or not.
- if (activeElem.min) {
- if (jsRuleSets_obj.isSet(activeElem)) {
- if (!jsRuleSets_obj.min(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'min',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- validElem = false;
- }
- }
- }
-
- // To Check the Value is grater than max or not.
- if (activeElem.max) {
- if (jsRuleSets_obj.isSet(activeElem)) {
- if (!jsRuleSets_obj.max(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'max',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- validElem = false;
- }
- }
- }
-
- // To Check the Entered E-mail is Valid or Not.
- if (activeElem.type == 'email') {
- if (jsRuleSets_obj.isSet(activeElem)) {
- if (!jsRuleSets_obj.email(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'email',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- validElem = false;
- }
- }
- }
-
- // To Compare the Password is Same or Not with Re-Password.
- // TODO: Implement Simplified Comparison.
- if (activeElem.type == 'password') {
- if (jsRuleSets_obj.isSet(activeElem)) {
- if (!jsRuleSets_obj.compare(activeElem)) {
- log.push({
- 'el': activeElem,
- 'type': 'password',
- 'id': activeElem.name + __err_id_suffix_rand_hash
- });
- firstErrorHit = activeElem.name + __err_id_suffix_rand_hash;
- validElem = false;
- }
- }
- } // If valid, then reset validation message.
-
- if (true === validElem) {
- //jsLogger.out('Valid Elem', activeElem);
- if (activeElem.name !== '') {
- var elem = document.getElementById(activeElem.name + __err_id_suffix_rand_hash);
- if (typeof (elem) !== 'undefined' && elem !== null) {
- // Remove element to avoid un-necessary buffer.
- elem.remove();
- }
- }
- }
- // If error occurred, then locate that error
- if (false !== firstErrorHit) {
- //helper.scrollToItem(firstErrorHit);
- }
- // }
- // Return overall log report of validation.
-
- return log;
- };
- /*
- * To Check, whether the element have value or not.
- */
- this.isSet = function (elem) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- var status = true;
- var value = elem.value;
- //TODO: Implement suitable solution for this.
- if (value.length === 0 || value === '' || value === ' ' || value === '[]') status = false;
- return status;
- };
- /*
- * To Check Element with Min Condition.
- */
- this.min = function (elem) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- var status = true;
- var value = elem.value;
- var min = elem.min;
- //TODO: Implement suitable solution for this.
- if (value.length < min && value.length != 0) status = false;
- return status;
- };
- /*
- * To Check Element with Max Condition.
- */
- this.max = function (elem) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- var status = true;
- var value = elem.value;
- var max = elem.max;
- //TODO: Implement suitable solution for this.
- if (value.length > max && value.length != 0) status = false;
- return status;
- };
- /*
- * To Check Element Email is Valid or Not.
- */
- this.email = function (elem) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- var status = false;
- var email = elem.value;
- if (typeof email === 'undefined') return false;
- // To Validate Email.
- // Convert to Native String Format.
- email = email.toString();
- // To Check it as String or Not.
- if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
- // Valid Email.
- status = true;
- }
- if (!email) status = false;
- return status;
- };
- /*
- * To Check Element's file is valid or not.
- */
- this.file = function (elem) {
- var list_to_allow = elem.target.getAttribute('data-extensions');
- var target = elem.target;
- var list_to_allow_array;
- var file_response;
- if ('' === list_to_allow) return true;
- // Slit into array of extensions.
- if (-1 === list_to_allow.indexOf(',')) {
- list_to_allow_array = [list_to_allow];
- } else {
- list_to_allow_array = list_to_allow.split(',');
- }
- // Get file name.
- var fileName = target.value;
- // Convert to lower case for native validation.
- fileName = fileName.toLowerCase();
- file_response = (new RegExp('(' + list_to_allow_array.join('|').replace(/\./g, '\\.') + ')$')).test(fileName);
- if (false === file_response) {
- alert('Allowed file types are "' + list_to_allow + '" !');
- // Reset file type.
- elem.target.value = '';
- return false;
- }
- return true;
- };
- /*
- * To Check Element Phone Value is Valid or Not.
- */
- this.phone = function (elem, pattern) {
- // If field is not required, then return "true".
- if (false === elem.required) return true;
- var status = true;
- if (elem.value === '') status = false;
- return status;
- };
- /*
- * To Compare two Elements Values.
- */
- this.compare = function (elem1) {
- var status = false;
- // If field is not required, then return "true".
- if (false === elem1.required) status = true;
- var elem2_id = elem1.getAttribute('data-check');
- if (typeof elem2_id == 'undefined' || elem2_id == null) status = false;
- if (elem2_id === null) elem2_id = elem1.getAttribute('data-parent');
- if (elem2_id === null) {
- status = false;
- } else {
- elem2_id = elem2_id.toString();
- var elem2 = document.getElementById(elem2_id);
- if (elem1.value === elem2.value) status = true;
- }
- //jsLogger.out('Compare Status', status);
- return status;
- };
-}
-/**
- * To Manage JsValidator Errors.
- */
-function jsFormError() {
- // Global constant to specify, error happened or not.
- this.errorHit = false;
- // Error Css.
- this.errorCss = false;
- // Success Css.
- this.successCss = false;
- /*
- * Initiate overall form error handler.
- */
- this.init = function () {
- this.errorHit = false;
- this.errorCss = 'border-color: red;border-radius: 5px;color: red;';
- this.successCss = 'border-color: green;border-radius: 5px;color: green;';
- };
- /*
- * Form error log.
- */
- this.log = function () {
- // jsLogger.out('Form Error Hit', this.errorHit);
- };
- /*
- * Form error style.
- */
- this.style = function (css) {
- this.errorCss = css.error;
- this.successCss = css.success;
- };
-}
-/**
- * For manage overall logging with validator.
- */
-var jsLogger = {
- status: function () {
- // return jsValidator.option.log;
- return '[]';
- },
- /*
- * Simple log with "heading" and "message".
- */
- out: function (heading, message) {
-
- if (true !== this.status()) return false;
- console.log('======' + heading + '======');
- console.log(message);
- console.log('------------------------');
- },
- /*
- * For bulk data logging.
- */
- bulk: function (data) {
- if (true !== this.status()) return false;
- console.log(data);
- },
- /*
- * For log data with table.
- */
- table: function (data) {
- if (true !== this.status()) return false;
- console.table(data);
- }
-};
-/**
- * General Helping methods.jsField_obj
- */
-var helper = {
- /*
- * To check the keyboard action is window action or not.
- */
- isWindowAction: function (event) {
- // Getting the event to be triggered.
- var theEvent = event || window.event;
- // Getting the type of event or code.
- var key = theEvent.shiftKey || theEvent.which;
- // Check with list of code and ignore holding.
- // Tab, Space, Home, End, Up, Down, Left, Right...
- if (key === 9 || key === 0 || key === 8 || key === 32 || key === 13 || key === 8 || (key >= 35 && key <= 40)) {
- return true;
- } // If not in list then check return with corresponding data.
-
- key = String.fromCharCode(key);
- // Return also if length is 0.
- if (key.length === 0) return true;
- // Finally return "false" for general keys.
- return false;
- },
- /*
- * To Scroll Up / Down to notify the item that have validation message.
- */
- scrollToError: function (validateResponse) {
- var dummy_id = '__header_error_target_temp';
- var active_class = validateResponse.getClass();
-
- if (false === active_class) {
- jsLogger.out('Active Class Error', 'ACTIVE CLASS NOT DEFINED, GET :' + active_class);
- return false;
- }
-
- if (0 === document.getElementsByClassName(active_class).length) return false;
- // Getting current ID of the element.
- var active_id = document.getElementsByClassName(active_class)[0].id;
- // Update first element with dummy index ID.
- document.getElementsByClassName(active_class)[0].setAttribute('id', dummy_id);
- // Forming ID.
- var id = document.getElementsByClassName(active_class)[0].id;
- // Retrieve the element name.
- var elem_name = active_id.replace(__err_id_suffix_rand_hash, '');
- // Taking active element to navigate.
- var top = document.getElementsByName(elem_name)[0].offsetTop;
- // Format as ID.
- id = '#' + id;
- // Navigate to ID.
- // window.location.href = id;
- // Scroll to error element as close as possible.
- window.scroll(0, parseInt(top) - 15);
- // Restore with actual ID.
- document.getElementsByClassName(active_class)[0].setAttribute('id', active_id);
- // Remove the navigated value.
- this.removeHash(id);
- },
- /*
- * To Scroll Up / Down to notify the item that have validation message.
- */
- scrollToItem: function (item) {
- // Form hash value.
- var hash = item;
- // If "#" is missing, then add back to the ID.
- if (-1 === hash.indexOf('#')) hash = '#' + hash;
- // Navigate with the hash value.
- window.location.href = hash;
- // Remove the navigated value.
- this.removeHash(hash);
- },
- /*
- * To remove the hash value from the URL.
- */
- removeHash: function (hash) {
- // Getting the actual URL.
- var path = window.location.href;
- // Replacing the URL with specific hash value.
- path = path.replace(hash, '');
- // Update to url history.
- window.history.pushState('', 'Title', path);
- }
-};
-/**
- * Simple library for Pattern.
- */
-function pattern() {
- /*
- * To generate pattern from element attribute.
- */
- this.getDefault = function (event, originalPattern) {
- if (typeof originalPattern == 'undefined') originalPattern = '';
- // Getting special characters list.
- var allow_special = event.target.getAttribute('data-allowSpecial');
- var pattern = event.target.pattern;
- console.log(pattern.length);
- var defaultPattern;
- // Set default values for special characters.
- if (!allow_special && allow_special === null) allow_special = '';
- // Format to string.
- allow_special = allow_special.toString();
- if (pattern !== '' && pattern.length > 0 && pattern !== null) {
- defaultPattern = pattern;
- } else {
- defaultPattern = '^[' + originalPattern + allow_special + ']+$';
- }
- return defaultPattern;
- };
- /*
- * To validate event with the pattern.
- */
- this.validate = function (event, pattern) {
- // Managing the Pattern.
- var defaultPattern = this.getDefault(event, pattern);
- // Validate with special formed pattern.
- var regex = new RegExp(defaultPattern);
- // Validation with Code.
- var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
- return regex.test(key);
- };
-}
-/**
- * To Manage all kind of error response.
- */
-function validationResponse() {
- this.active_class = false;
- /*
- * Initiating the Response handler.
- */
- this.init = function (errorList, option) {
- this.errorMessage = option.message;
- // Updating the class.
- this.active_class = option.errorClass;
- // var errorElements = option.errorElem;
- // jsLogger.out('Errors', errorList);
- this.input(errorList.input);
- this.select(errorList.select);
- this.textArea(errorList.textArea);
-
- };
- /*
- * To handle the "input" element.
- */
- this.input = function (elem) {
- // Initiate process for Input.
- this.process(elem);
- };
- /*
- * To handle the "select" element.
- */
- this.select = function (elem) {
- // Initiate process for Select.
- this.process(elem);
- };
- /*
- * To return active class for validation response style.
- */
- this.getClass = function () {
- return this.active_class;
- };
- /*
- * To handle the "textArea" element.
- */
- this.textArea = function (elem) {
- // Initiate process for TextArea.
- this.process(elem);
- };
- /*
- * To process all handlers.
- */
- this.process = function (elem) {
- // Process with initial response.
- var elementDefaultResponse = '';
- // Get active class for error response element
- var active_class = this.getClass();
- for (var i in elem) {
- // jsLogger.out('Element', document.getElementById(elem[i].id));
- if (elem[i].el && true === elem[i].el.required) {
- // Manage active element.
- var activeElem = elem[i];
- var errorType = elem[i].type;
- // Fetch from Element's direct message.
- elementDefaultResponse = this.template(activeElem, errorType);
- var spanTag = document.getElementById(activeElem.id);
- // jsLogger.out('Element Hit', errorType);
- // Create new response Message SPAN.
- if (typeof spanTag === 'undefined' || spanTag === 'undefined' || spanTag === null) {
- // jsLogger.out('Element Found', false);
- spanTag = document.createElement('span');
- spanTag.setAttribute('id', activeElem.id);
- spanTag.setAttribute('class', active_class);
- spanTag.innerHTML = elementDefaultResponse;
- } else {
- // Re-use Existing response Message SPAN.
- spanTag.innerHTML = elementDefaultResponse;
- }
- // Append HTML response to the Element.
- activeElem.el.parentNode.insertBefore(spanTag, activeElem.el.nextSibling);
- }
- }
- };
- /*
- * Perform template creation and update.
- */
- this.template = function (activeElem, errorType) {
- //jsLogger.out('error Type 0', errorType);
- var errorIndex = '';
- var activeError = '';
- // Getting error response message from elemnet.
- var elementDefaultResponse = activeElem.el.getAttribute('data-message');
- if (typeof elementDefaultResponse === 'undefined' || elementDefaultResponse === '' || elementDefaultResponse === null) {
- // Sanity check with error message object.
- if (typeof this.errorMessage !== 'undefined' && typeof this.errorMessage[errorType] !== 'undefined') {
- // Getting error type. [ex. Required, Min, Max...]
- errorType = this.errorMessage[errorType];
-
- // activeElem.el.getAttribute('data-message');
- if (errorType) {
- //jsLogger.out('errorType', errorType);
- activeError = errorType;
- // If error type is Min or Max, then it will proceed responsive.
- if (activeElem.type == 'min' || activeElem.type == 'max') {
- if ('min' == activeElem.type) errorIndex = activeElem.el.min;
- if ('max' == activeElem.type) errorIndex = activeElem.el.max;
- activeError = activeError.replace('[INDEX]', errorIndex);
- }
- }
- } else {
- activeError = this.default(errorType);
- }
- elementDefaultResponse = activeError;
- }
- return elementDefaultResponse;
- };
- /*
- * Default error handling messages.
- * If user not specify the messages,
- * then it will be replaces.
- */
- this.default = function (errorType) {
- var active_class = this.getClass();
- var errorMessages = {
- required: 'This field is required.',
- min: 'This field length is too low.',
- max: 'This field length is exceeds the limit.',
- password: 'Password does not match.',
- email: 'Email is not valid.',
- file: 'This file is not allowed.'
- };
- if (typeof errorType !== 'string') return false;
- if (typeof errorMessages[errorType] === 'undefined') return false;
- return errorMessages[errorType];
- };
-}
\ No newline at end of file