@syncfusion/ej2-inputs
Version:
A package of Essential JS 2 input components such as Textbox, Color-picker, Masked-textbox, Numeric-textbox, Slider, Upload, and Form-validator that is used to get input from the users.
950 lines (949 loc) • 42.8 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { selectAll, select, createElement, Base, detach } from '@syncfusion/ej2-base';
import { extend, isNullOrUndefined, EventHandler } from '@syncfusion/ej2-base';
import { Property, NotifyPropertyChanges, Event, onIntlChange } from '@syncfusion/ej2-base';
import { Internationalization, L10n } from '@syncfusion/ej2-base';
/**
* global declarations
*/
export var regex = {
/* eslint-disable no-useless-escape */
EMAIL: new RegExp('^[A-Za-z0-9._%+-]{1,}@[A-Za-z0-9._%+-]{1,}([.]{1}[a-zA-Z0-9]{2,}' +
'|[.]{1}[a-zA-Z0-9]{2,4}[.]{1}[a-zA-Z0-9]{2,4})$'),
/* eslint-disable-next-line security/detect-unsafe-regex */
URL: /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/m,
DATE_ISO: new RegExp('^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$'),
DIGITS: new RegExp('^[0-9]*$'),
PHONE: new RegExp('^[+]?[0-9]{9,13}$'),
CREDITCARD: new RegExp('^\\d{13,16}$')
/* eslint-enable no-useless-escape */
};
/**
* ErrorOption values
*
* @private
*/
export var ErrorOption;
(function (ErrorOption) {
/**
* Defines the error message.
*/
ErrorOption[ErrorOption["Message"] = 0] = "Message";
/**
* Defines the error element type.
*/
ErrorOption[ErrorOption["Label"] = 1] = "Label";
})(ErrorOption || (ErrorOption = {}));
/**
* FormValidator class enables you to validate the form fields based on your defined rules
* ```html
* <form id='formId'>
* <input type='text' name='Name' />
* <input type='text' name='Age' />
* </form>
* <script>
* let formObject = new FormValidator('#formId', {
* rules: { Name: { required: true }, Age: { range: [18, 30] } };
* });
* formObject.validate();
* </script>
* ```
*/
var FormValidator = /** @class */ (function (_super) {
__extends(FormValidator, _super);
/**
* Initializes the FormValidator.
*
* @param {string | HTMLFormElement} element - Specifies the element to render as component.
* @param {FormValidatorModel} options - Specifies the FormValidator model.
* @private
*/
function FormValidator(element, options) {
var _this = _super.call(this, options, element) || this;
_this.validated = [];
_this.errorRules = [];
_this.allowSubmit = false;
_this.required = 'required';
_this.infoElement = null;
_this.inputElement = null;
_this.selectQuery = 'input:not([type=reset]):not([type=button]), select, textarea';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_this.localyMessage = {};
/**
* Specifies the default messages for validation rules.
*
* @default { List of validation message }
*/
_this.defaultMessages = {
required: 'This field is required.',
email: 'Please enter a valid email address.',
url: 'Please enter a valid URL.',
date: 'Please enter a valid date.',
dateIso: 'Please enter a valid date ( ISO ).',
creditcard: 'Please enter valid card number',
number: 'Please enter a valid number.',
digits: 'Please enter only digits.',
maxLength: 'Please enter no more than {0} characters.',
minLength: 'Please enter at least {0} characters.',
rangeLength: 'Please enter a value between {0} and {1} characters long.',
range: 'Please enter a value between {0} and {1}.',
max: 'Please enter a value less than or equal to {0}.',
min: 'Please enter a value greater than or equal to {0}.',
regex: 'Please enter a correct value.',
tel: 'Please enter a valid phone number.',
pattern: 'Please enter a correct pattern value.',
equalTo: 'Please enter the valid match text'
};
if (typeof _this.rules === 'undefined') {
_this.rules = {};
}
_this.l10n = new L10n('formValidator', _this.defaultMessages, _this.locale);
if (_this.locale) {
_this.localeFunc();
}
onIntlChange.on('notifyExternalChange', _this.afterLocalization, _this);
element = typeof element === 'string' ? select(element, document) : element;
// Set novalidate to prevent default HTML5 form validation
if (_this.element != null) {
_this.element.setAttribute('novalidate', '');
_this.inputElements = selectAll(_this.selectQuery, _this.element);
_this.createHTML5Rules();
_this.wireEvents();
}
else {
return undefined;
}
return _this;
}
FormValidator_1 = FormValidator;
/* eslint-enable @typescript-eslint/no-explicit-any */
/**
* Add validation rules to the corresponding input element based on `name` attribute.
*
* @param {string} name `name` of form field.
* @param {Object} rules Validation rules for the corresponding element.
* @returns {void}
*/
FormValidator.prototype.addRules = function (name, rules) {
if (name) {
// eslint-disable-next-line no-prototype-builtins
if (this.rules.hasOwnProperty(name)) {
extend(this.rules["" + name], rules, {});
}
else {
this.rules["" + name] = rules;
}
}
};
/**
* Remove validation to the corresponding field based on name attribute.
* When no parameter is passed, remove all the validations in the form.
*
* @param {string} name Input name attribute value.
* @param {string[]} rules List of validation rules need to be remove from the corresponding element.
* @returns {void}
*/
FormValidator.prototype.removeRules = function (name, rules) {
if (!name && !rules) {
this.rules = {};
}
else if (this.rules["" + name] && !rules) {
delete this.rules["" + name];
}
else if (!isNullOrUndefined(this.rules["" + name] && rules)) {
for (var i = 0; i < rules.length; i++) {
delete this.rules["" + name][rules[parseInt(i.toString(), 10)]];
}
}
else {
return;
}
};
/**
* Validate the current form values using defined rules.
* Returns `true` when the form is valid otherwise `false`
*
* @param {string} selected - Optional parameter to validate specified element.
* @returns {boolean} - Returns form validation status.
*/
FormValidator.prototype.validate = function (selected) {
var rules = Object.keys(this.rules);
if (selected && rules.length) {
this.validateRules(selected);
//filter the selected element it don't have any valid input element
return rules.indexOf(selected) !== -1 && this.errorRules.filter(function (data) {
return data.name === selected;
}).length === 0;
}
else {
this.errorRules = [];
for (var _i = 0, rules_1 = rules; _i < rules_1.length; _i++) {
var name_1 = rules_1[_i];
this.validateRules(name_1);
}
return this.errorRules.length === 0;
}
};
/**
* Reset the value of all the fields in form.
*
* @returns {void}
*/
FormValidator.prototype.reset = function () {
this.element.reset();
this.clearForm();
};
/**
* Get input element by name.
*
* @param {string} name - Input element name attribute value.
* @returns {HTMLInputElement} - Returns the input element.
*/
FormValidator.prototype.getInputElement = function (name) {
this.inputElement = (select('[name="' + name + '"]', this.element));
return this.inputElement;
};
/**
* Destroy the form validator object and error elements.
*
* @returns {void}
*/
FormValidator.prototype.destroy = function () {
this.reset();
this.unwireEvents();
this.rules = {};
var elements = selectAll('.' + this.errorClass + ', .' + this.validClass, this.element);
for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
var element = elements_1[_i];
detach(element);
}
_super.prototype.destroy.call(this);
this.infoElement = null;
onIntlChange.off('notifyExternalChange', this.afterLocalization);
};
/**
* @param {FormValidatorModel} newProp - Returns the dynamic property value of the component.
* @param {FormValidatorModel} oldProp - Returns the previous property value of the component.
* @returns {void}
* @private
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
FormValidator.prototype.onPropertyChanged = function (newProp, oldProp) {
for (var _i = 0, _a = Object.keys(newProp); _i < _a.length; _i++) {
var prop = _a[_i];
switch (prop) {
case 'locale':
this.localeFunc();
break;
}
}
};
/**
* @private
* @returns {void}
*/
FormValidator.prototype.localeFunc = function () {
for (var _i = 0, _a = Object.keys(this.defaultMessages); _i < _a.length; _i++) {
var key = _a[_i];
this.l10n.setLocale(this.locale);
var value = this.l10n.getConstant(key);
this.localyMessage["" + key] = value;
}
};
/**
* @private
* @returns {string} - Returns the component name.
*/
FormValidator.prototype.getModuleName = function () {
return 'formvalidator';
};
/**
* @param {any} args - Specifies the culture name.
* @returns {void}
* @private
*/
FormValidator.prototype.afterLocalization = function (args) {
this.locale = args.locale;
this.localeFunc();
};
/**
* Allows you to refresh the form validator base events to the elements inside the form.
*
* @returns {void}
*/
FormValidator.prototype.refresh = function () {
this.unwireEvents();
this.inputElements = selectAll(this.selectQuery, this.element);
this.wireEvents();
};
FormValidator.prototype.clearForm = function () {
this.errorRules = [];
this.validated = [];
var elements = selectAll(this.selectQuery, this.element);
for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
var element = elements_2[_i];
var input = element;
input.removeAttribute('aria-invalid');
var inputParent = input.parentElement;
var grandParent = inputParent.parentElement;
if (inputParent.classList.contains('e-control-wrapper') || inputParent.classList.contains('e-wrapper') ||
(input.classList.contains('e-input') && inputParent.classList.contains('e-input-group'))) {
inputParent.classList.remove(this.errorClass);
}
else if ((grandParent != null) && (grandParent.classList.contains('e-control-wrapper') ||
grandParent.classList.contains('e-wrapper'))) {
grandParent.classList.remove(this.errorClass);
}
else {
input.classList.remove(this.errorClass);
}
if (input.name.length > 0) {
this.getInputElement(input.name);
this.getErrorElement(input.name);
this.hideMessage(input.name);
}
if (inputParent.classList.contains('e-control-wrapper') || inputParent.classList.contains('e-wrapper') ||
(input.classList.contains('e-input') && inputParent.classList.contains('e-input-group'))) {
inputParent.classList.remove(this.validClass);
}
else if ((grandParent != null) && (grandParent.classList.contains('e-control-wrapper') ||
grandParent.classList.contains('e-wrapper'))) {
grandParent.classList.remove(this.validClass);
}
else {
input.classList.remove(this.validClass);
}
}
};
FormValidator.prototype.createHTML5Rules = function () {
var defRules = ['required', 'validateHidden', 'regex', 'rangeLength', 'maxLength', 'minLength', 'dateIso', 'digits',
'pattern', 'data-val-required', 'type', 'data-validation', 'min', 'max', 'range', 'equalTo', 'data-val-minlength-min',
'data-val-equalto-other', 'data-val-maxlength-max', 'data-val-range-min', 'data-val-regex-pattern', 'data-val-length-max',
'data-val-creditcard', 'data-val-phone'];
var acceptedTypes = ['hidden', 'email', 'url', 'date', 'number', 'tel'];
for (var _i = 0, _a = (this.inputElements); _i < _a.length; _i++) {
var input = _a[_i];
// Default attribute rules
var allRule = {};
for (var _b = 0, defRules_1 = defRules; _b < defRules_1.length; _b++) {
var rule = defRules_1[_b];
if (input.getAttribute(rule) !== null) {
switch (rule) {
case 'required':
this.defRule(input, allRule, rule, input.required);
break;
case 'data-validation':
rule = input.getAttribute(rule);
this.defRule(input, allRule, rule, true);
break;
case 'type':
if (acceptedTypes.indexOf(input.type) !== -1) {
this.defRule(input, allRule, input.type, true);
}
break;
case 'rangeLength':
case 'range':
this.defRule(input, allRule, rule, JSON.parse(input.getAttribute(rule)));
break;
case 'equalTo':
{
var id = input.getAttribute(rule);
this.defRule(input, allRule, rule, id);
}
break;
default:
if (input.getAttribute('data-val') === 'true') {
this.annotationRule(input, allRule, rule, input.getAttribute(rule));
}
else {
this.defRule(input, allRule, rule, input.getAttribute(rule));
}
}
}
}
//adding pattern type validation
if (Object.keys(allRule).length !== 0) {
this.addRules(input.name, allRule);
}
}
};
FormValidator.prototype.annotationRule = function (input, ruleCon, ruleName, value) {
var annotationRule = ruleName.split('-');
var rulesList = ['required', 'creditcard', 'phone', 'maxlength', 'minlength', 'range', 'regex', 'equalto'];
var ruleFirstName = annotationRule[annotationRule.length - 1];
var ruleSecondName = annotationRule[annotationRule.length - 2];
if (rulesList.indexOf(ruleFirstName) !== -1) {
switch (ruleFirstName) {
case 'required':
this.defRule(input, ruleCon, 'required', value);
break;
case 'creditcard':
this.defRule(input, ruleCon, 'creditcard', value);
break;
case 'phone':
this.defRule(input, ruleCon, 'tel', value);
break;
}
}
else if (rulesList.indexOf(ruleSecondName) !== -1) {
switch (ruleSecondName) {
case 'maxlength':
this.defRule(input, ruleCon, 'maxLength', value);
break;
case 'minlength':
this.defRule(input, ruleCon, 'minLength', value);
break;
case 'range':
{
var minvalue = input.getAttribute('data-val-range-min');
var maxvalue = input.getAttribute('data-val-range-max');
this.defRule(input, ruleCon, 'range', [minvalue, maxvalue]);
}
break;
case 'equalto':
{
var id = input.getAttribute(ruleName).split('.');
this.defRule(input, ruleCon, 'equalTo', id[id.length - 1]);
}
break;
case 'regex':
this.defRule(input, ruleCon, 'regex', value);
break;
}
}
};
FormValidator.prototype.defRule = function (input, ruleCon, ruleName, value) {
var message = input.getAttribute('data-' + ruleName + '-message');
var annotationMessage = input.getAttribute('data-val-' + ruleName);
var customMessage;
if (this.rules[input.name] && ruleName !== 'validateHidden' && ruleName !== 'hidden') {
this.getInputElement(input.name);
customMessage = this.getErrorMessage(this.rules[input.name]["" + ruleName], ruleName);
}
if (message) {
value = [value, message];
}
else if (annotationMessage) {
value = [value, annotationMessage];
}
else if (customMessage) {
value = [value, customMessage];
}
ruleCon["" + ruleName] = value;
};
// Wire events to the form elements
FormValidator.prototype.wireEvents = function () {
for (var _i = 0, _a = (this.inputElements); _i < _a.length; _i++) {
var input = _a[_i];
if (FormValidator_1.isCheckable(input)) {
EventHandler.add(input, 'click', this.clickHandler, this);
}
else if (input.tagName === 'SELECT') {
EventHandler.add(input, 'change', this.changeHandler, this);
}
else {
EventHandler.add(input, 'focusout', this.focusOutHandler, this);
EventHandler.add(input, 'keyup', this.keyUpHandler, this);
}
}
EventHandler.add(this.element, 'submit', this.submitHandler, this);
EventHandler.add(this.element, 'reset', this.resetHandler, this);
};
// UnWire events to the form elements
FormValidator.prototype.unwireEvents = function () {
for (var _i = 0, _a = (this.inputElements); _i < _a.length; _i++) {
var input = _a[_i];
EventHandler.clearEvents(input);
}
EventHandler.remove(this.element, 'submit', this.submitHandler);
EventHandler.remove(this.element, 'reset', this.resetHandler);
};
// Handle input element focusout event
FormValidator.prototype.focusOutHandler = function (e) {
this.trigger('focusout', e);
//FormValidator.triggerCallback(this.focusout, e);
var element = e.target;
if (this.rules[element.name]) {
if (this.rules[element.name][this.required] || element.value.length > 0) {
this.validate(element.name);
}
else if (this.validated.indexOf(element.name) === -1) {
this.validated.push(element.name);
}
}
};
// Handle input element keyup event
FormValidator.prototype.keyUpHandler = function (e) {
this.trigger('keyup', e);
var element = e.target;
// List of keys need to prevent while validation
var excludeKeys = [16, 17, 18, 20, 35, 36, 37, 38, 39, 40, 45, 144, 225];
if (e.which === 9 && (!this.rules[element.name] || (this.rules[element.name] && !this.rules[element.name][this.required]))) {
return;
}
if (this.validated.indexOf(element.name) !== -1 && this.rules[element.name] && excludeKeys.indexOf(e.which) === -1) {
this.validate(element.name);
}
};
// Handle input click event
FormValidator.prototype.clickHandler = function (e) {
this.trigger('click', e);
var element = e.target;
// If element type is not submit allow validation
if (element.type !== 'submit') {
this.validate(element.name);
}
else if (element.getAttribute('formnovalidate') !== null) {
// Prevent form validation, if submit button has formnovalidate attribute
this.allowSubmit = true;
}
};
// Handle input change event
FormValidator.prototype.changeHandler = function (e) {
this.trigger('change', e);
var element = e.target;
this.validate(element.name);
};
// Handle form submit event
FormValidator.prototype.submitHandler = function (e) {
this.trigger('submit', e);
//FormValidator.triggerCallback(this.submit, e);
// Prevent form submit if validation failed
if (!this.allowSubmit && !this.validate()) {
e.preventDefault();
}
else {
this.allowSubmit = false;
}
};
// Handle form reset
FormValidator.prototype.resetHandler = function () {
this.clearForm();
};
// Validate each rule based on input element name
FormValidator.prototype.validateRules = function (name) {
if (!this.rules["" + name]) {
return;
}
var rules = Object.keys(this.rules["" + name]);
var hiddenType = false;
var validateHiddenType = false;
var vhPos = rules.indexOf('validateHidden');
var hPos = rules.indexOf('hidden');
this.getInputElement(name);
if (hPos !== -1) {
hiddenType = true;
}
if (vhPos !== -1) {
validateHiddenType = true;
}
if (!hiddenType || (hiddenType && validateHiddenType)) {
if (vhPos !== -1) {
rules.splice(vhPos, 1);
}
if (hPos !== -1) {
rules.splice((hPos - 1), 1);
}
this.getErrorElement(name);
for (var _i = 0, rules_2 = rules; _i < rules_2.length; _i++) {
var rule = rules_2[_i];
var errorMessage = this.getErrorMessage(this.rules["" + name]["" + rule], rule);
var errorRule = { name: name, message: errorMessage };
var eventArgs = {
inputName: name,
element: this.inputElement,
message: errorMessage
};
if (!this.isValid(name, rule) && !this.inputElement.classList.contains(this.ignore)) {
this.removeErrorRules(name);
this.errorRules.push(errorRule);
// Set aria attributes to invalid elements
this.inputElement.setAttribute('aria-invalid', 'true');
this.inputElement.setAttribute('aria-describedby', this.inputElement.id + '-info');
var inputParent = this.inputElement.parentElement;
var grandParent = inputParent.parentElement;
if (inputParent.classList.contains('e-control-wrapper') || inputParent.classList.contains('e-wrapper') ||
(this.inputElement.classList.contains('e-input') && inputParent.classList.contains('e-input-group'))) {
inputParent.classList.add(this.errorClass);
inputParent.classList.remove(this.validClass);
}
else if ((grandParent != null) && (grandParent.classList.contains('e-control-wrapper') ||
grandParent.classList.contains('e-wrapper'))) {
grandParent.classList.add(this.errorClass);
grandParent.classList.remove(this.validClass);
}
else {
this.inputElement.classList.add(this.errorClass);
this.inputElement.classList.remove(this.validClass);
}
if (!this.infoElement) {
this.createErrorElement(name, errorRule.message, this.inputElement);
}
else {
this.showMessage(errorRule);
}
eventArgs.errorElement = this.infoElement;
eventArgs.status = 'failure';
if (inputParent.classList.contains('e-control-wrapper') || inputParent.classList.contains('e-wrapper') ||
(this.inputElement.classList.contains('e-input') && inputParent.classList.contains('e-input-group'))) {
inputParent.classList.add(this.errorClass);
inputParent.classList.remove(this.validClass);
}
else if ((grandParent != null) && (grandParent.classList.contains('e-control-wrapper') ||
grandParent.classList.contains('e-wrapper'))) {
grandParent.classList.add(this.errorClass);
grandParent.classList.remove(this.validClass);
}
else {
this.inputElement.classList.add(this.errorClass);
this.inputElement.classList.remove(this.validClass);
}
this.optionalValidationStatus(name, eventArgs);
this.trigger('validationComplete', eventArgs);
// Set aria-required to required rule elements
if (rule === 'required') {
this.inputElement.setAttribute('aria-required', 'true');
}
break;
}
else {
this.hideMessage(name);
eventArgs.status = 'success';
this.trigger('validationComplete', eventArgs);
}
}
}
else {
return;
}
};
// Update the optional validation status
FormValidator.prototype.optionalValidationStatus = function (name, refer) {
if (!this.rules["" + name][this.required] && !this.inputElement.value.length && !isNullOrUndefined(this.infoElement)) {
this.infoElement.innerHTML = this.inputElement.value;
this.infoElement.setAttribute('aria-invalid', 'false');
refer.status = '';
this.hideMessage(name);
}
};
// Check the input element whether it's value satisfy the validation rule or not
FormValidator.prototype.isValid = function (name, rule) {
var params = this.rules["" + name]["" + rule];
var param = (params instanceof Array && typeof params[1] === 'string') ? params[0] : params;
var currentRule = this.rules["" + name]["" + rule];
var dateFormat = ((rule === 'min' || rule === 'max') && this.rules['' + name].date &&
typeof (this.rules['' + name].date) === 'string') ? this.rules['' + name].date : null;
var args = { value: this.inputElement.value,
param: param, element: this.inputElement, formElement: this.element, format: dateFormat, culture: this.locale };
this.trigger('validationBegin', args);
if (!args.param && rule === 'required') {
return true;
}
if (currentRule && typeof currentRule[0] === 'function') {
var fn = currentRule[0];
return fn.call(this, { element: this.inputElement, value: this.inputElement.value });
}
else if (FormValidator_1.isCheckable(this.inputElement)) {
if (rule !== 'required') {
return true;
}
return selectAll('input[name="' + name + '"]:checked', this.element).length > 0;
}
else {
return FormValidator_1.checkValidator["" + rule](args);
}
};
// Return default error message or custom error message
FormValidator.prototype.getErrorMessage = function (ruleValue, rule) {
var message = this.inputElement.getAttribute('data-' + rule + '-message') ?
this.inputElement.getAttribute('data-' + rule + '-message') :
(ruleValue instanceof Array && typeof ruleValue[1] === 'string') ? ruleValue[1] :
(Object.keys(this.localyMessage).length !== 0) ? this.localyMessage["" + rule] : this.defaultMessages["" + rule];
var formats = message.match(/{(\d)}/g);
if (!isNullOrUndefined(formats)) {
for (var i = 0; i < formats.length; i++) {
var value = ruleValue instanceof Array ? ruleValue[parseInt(i.toString(), 10)] : ruleValue;
message = message.replace(formats[parseInt(i.toString(), 10)], value);
}
}
return message;
};
// Create error element based on name and error message
FormValidator.prototype.createErrorElement = function (name, message, input) {
var errorElement = createElement(this.errorElement, {
className: this.errorClass,
innerHTML: message,
attrs: { for: name }
});
// Create message design if errorOption is message
if (this.errorOption === ErrorOption.Message) {
errorElement.classList.remove(this.errorClass);
errorElement.classList.add('e-message');
errorElement = createElement(this.errorContainer, { className: this.errorClass, innerHTML: errorElement.outerHTML });
}
errorElement.id = this.inputElement.name + '-info';
// Append error message into MVC error message element
if (this.element.querySelector('[data-valmsg-for="' + input.id + '"]')) {
this.element.querySelector('[data-valmsg-for="' + input.id + '"]').appendChild(errorElement);
}
else if (input.hasAttribute('data-msg-containerid') === true) {
// Append error message into custom div element
var containerId = input.getAttribute('data-msg-containerid');
var divElement = select('#' + containerId, this.element);
divElement.appendChild(errorElement);
}
else if (this.customPlacement != null) {
// Call custom placement function if customPlacement is not null
this.customPlacement.call(this, this.inputElement, errorElement);
}
else {
var inputParent = this.inputElement.parentElement;
var grandParent = inputParent.parentElement;
if (inputParent.classList.contains('e-control-wrapper') || inputParent.classList.contains('e-wrapper')) {
grandParent.insertBefore(errorElement, inputParent.nextSibling);
}
else if (grandParent.classList.contains('e-control-wrapper') || grandParent.classList.contains('e-wrapper')) {
grandParent.parentElement.insertBefore(errorElement, grandParent.nextSibling);
}
else {
inputParent.insertBefore(errorElement, this.inputElement.nextSibling);
}
}
errorElement.style.display = 'block';
this.getErrorElement(name);
this.validated.push(name);
this.checkRequired(name);
};
// Get error element by name
FormValidator.prototype.getErrorElement = function (name) {
this.infoElement = select(this.errorElement + '.' + this.errorClass, this.inputElement.parentElement);
if (!this.infoElement) {
this.infoElement = select(this.errorElement + '.' + this.errorClass + '[for="' + name + '"]', this.element);
}
return this.infoElement;
};
// Remove existing rule from errorRules object
FormValidator.prototype.removeErrorRules = function (name) {
for (var i = 0; i < this.errorRules.length; i++) {
var rule = this.errorRules[parseInt(i.toString(), 10)];
if (rule.name === name) {
this.errorRules.splice(i, 1);
}
}
};
// Show error message to the input element
FormValidator.prototype.showMessage = function (errorRule) {
this.infoElement.style.display = 'block';
this.infoElement.innerHTML = errorRule.message;
this.checkRequired(errorRule.name);
};
// Hide error message based on input name
FormValidator.prototype.hideMessage = function (name) {
if (this.infoElement) {
this.infoElement.style.display = 'none';
this.removeErrorRules(name);
var inputParent = this.inputElement.parentElement;
var grandParent = inputParent.parentElement;
if (inputParent.classList.contains('e-control-wrapper') || inputParent.classList.contains('e-wrapper') ||
(this.inputElement.classList.contains('e-input') && inputParent.classList.contains('e-input-group'))) {
inputParent.classList.add(this.validClass);
inputParent.classList.remove(this.errorClass);
}
else if ((grandParent != null) && (grandParent.classList.contains('e-control-wrapper') || grandParent.classList.contains('e-wrapper'))) {
grandParent.classList.add(this.validClass);
grandParent.classList.remove(this.errorClass);
}
else {
this.inputElement.classList.add(this.validClass);
this.inputElement.classList.remove(this.errorClass);
}
this.inputElement.setAttribute('aria-invalid', 'false');
}
};
// Check whether the input element have required rule and its value is not empty
FormValidator.prototype.checkRequired = function (name) {
if (!this.rules["" + name][this.required] && !this.inputElement.value.length && !isNullOrUndefined(this.infoElement)) {
this.infoElement.innerHTML = this.inputElement.value;
this.infoElement.setAttribute('aria-invalid', 'false');
this.hideMessage(name);
}
};
// Return boolean result if the input have checkable or submit types
FormValidator.isCheckable = function (input) {
var inputType = input.getAttribute('type');
return inputType && (inputType === 'checkbox' || inputType === 'radio' || inputType === 'submit');
};
var FormValidator_1;
// List of function to validate the rules
FormValidator.checkValidator = {
required: function (option) {
return !isNaN(Date.parse(option.value)) ? !isNaN(new Date(option.value).getTime()) : option.value.toString().length > 0;
},
email: function (option) {
return regex.EMAIL.test(option.value);
},
url: function (option) {
return regex.URL.test(option.value);
},
dateIso: function (option) {
return regex.DATE_ISO.test(option.value);
},
tel: function (option) {
return regex.PHONE.test(option.value);
},
creditcard: function (option) {
return regex.CREDITCARD.test(option.value);
},
number: function (option) {
return !isNaN(Number(option.value)) && String(option.value).indexOf(' ') === -1;
},
digits: function (option) {
return regex.DIGITS.test(option.value);
},
maxLength: function (option) {
return option.value.length <= Number(option.param);
},
minLength: function (option) {
return option.value.length >= Number(option.param);
},
rangeLength: function (option) {
var param = option.param;
return option.value.length >= param[0] && option.value.length <= param[1];
},
range: function (option) {
var param = option.param;
return !isNaN(Number(option.value)) && Number(option.value) >= param[0] && Number(option.value) <= param[1];
},
date: function (option) {
if (!isNullOrUndefined(option.param) && (typeof (option.param) === 'string' && option.param !== '')) {
var globalize = option.culture && option.culture !== '' ? new Internationalization(option.culture) : new Internationalization;
var dateOptions = { format: option.param.toString(), type: 'dateTime', skeleton: 'yMd' };
var dateValue = globalize.parseDate(option.value, dateOptions);
return (!isNullOrUndefined(dateValue) && dateValue instanceof Date && !isNaN(+dateValue));
}
else {
return !isNaN(new Date(option.value).getTime());
}
},
max: function (option) {
if (!isNaN(Number(option.value))) {
// Maximum rule validation for number
return +option.value <= +option.param;
}
// Maximum rule validation for date
if (option.format && option.format !== '') {
var globalize = option.culture && option.culture !== '' ? new Internationalization(option.culture) : new Internationalization;
var dateOptions = { format: option.format.toString(), type: 'dateTime', skeleton: 'yMd' };
var dateValue = globalize.parseDate(option.value, dateOptions);
var maxValue = (typeof (option.param) === 'string') ? globalize.parseDate(JSON.parse(JSON.stringify(option.param)), dateOptions) : option.param;
return new Date(dateValue).getTime() <= new Date(maxValue).getTime();
}
else {
return new Date(option.value).getTime() <= new Date(JSON.parse(JSON.stringify(option.param))).getTime();
}
},
min: function (option) {
if (!isNaN(Number(option.value))) {
// Minimum rule validation for number
return +option.value >= +option.param;
}
else if ((option.value).indexOf(',') !== -1) {
var uNum = (option.value).replace(/,/g, '');
return parseFloat(uNum) >= Number(option.param); // Convert option.param to a number
}
else {
// Minimum rule validation for date
if (option.format && option.format !== '') {
var globalize = option.culture && option.culture !== '' ? new Internationalization(option.culture) : new Internationalization;
var dateOptions = { format: option.format.toString(), type: 'dateTime', skeleton: 'yMd' };
var dateValue = globalize.parseDate(option.value, dateOptions);
var minValue = (typeof (option.param) === 'string') ? globalize.parseDate(JSON.parse(JSON.stringify(option.param)), dateOptions) : option.param;
return new Date(dateValue).getTime() >= new Date(minValue).getTime();
}
else {
return new Date(option.value).getTime() >= new Date(JSON.parse(JSON.stringify(option.param))).getTime();
}
}
},
regex: function (option) {
/* eslint-disable-next-line security/detect-non-literal-regexp */
return new RegExp(option.param).test(option.value);
},
equalTo: function (option) {
var compareTo = option.formElement.querySelector('#' + option.param);
option.param = compareTo.value;
return option.param === option.value;
}
};
__decorate([
Property('')
], FormValidator.prototype, "locale", void 0);
__decorate([
Property('e-hidden')
], FormValidator.prototype, "ignore", void 0);
__decorate([
Property()
], FormValidator.prototype, "rules", void 0);
__decorate([
Property('e-error')
], FormValidator.prototype, "errorClass", void 0);
__decorate([
Property('e-valid')
], FormValidator.prototype, "validClass", void 0);
__decorate([
Property('label')
], FormValidator.prototype, "errorElement", void 0);
__decorate([
Property('div')
], FormValidator.prototype, "errorContainer", void 0);
__decorate([
Property(ErrorOption.Label)
], FormValidator.prototype, "errorOption", void 0);
__decorate([
Event()
], FormValidator.prototype, "focusout", void 0);
__decorate([
Event()
], FormValidator.prototype, "keyup", void 0);
__decorate([
Event()
], FormValidator.prototype, "click", void 0);
__decorate([
Event()
], FormValidator.prototype, "change", void 0);
__decorate([
Event()
], FormValidator.prototype, "submit", void 0);
__decorate([
Event()
], FormValidator.prototype, "validationBegin", void 0);
__decorate([
Event()
], FormValidator.prototype, "validationComplete", void 0);
__decorate([
Event()
], FormValidator.prototype, "customPlacement", void 0);
FormValidator = FormValidator_1 = __decorate([
NotifyPropertyChanges
], FormValidator);
return FormValidator;
}(Base));
export { FormValidator };