diff --git a/README.md b/README.md index 6dd2c6e..1fc61ea 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,297 @@ # Fusion Form Validator and Utilities +> #### Form Validation plugin with fluent chainable utility methods. -Form Validation plugin with tools to handle AJAX and XHR response. +
+ +## Installation + +--- + +[Bootstrap](https://getbootstrap.com/) ^5.x, and [Fontawesome](https://fontawesome.com/) ^6.x are required. + +No worries, the above requirements are shipped along with the Fusion Form Validator package.\ +Simply head over to the [latest release page](https://github.com/Bien-Glitch/fusion.form.validator/releases/latest) and download the assets to stay up to date. + +> ### Once the Fusion Form Validator asset has been downloaded: +> - The ***Fusion Form Validator*** can be found in the `src` folder. +> - The dependencies ***(Bootstrap & Fontawesome)*** can be found in the `plugins` folder. +> - Copy the files / folders in the `src` and `plugins` folder to wherever you like in the root of your Web-Project. + +\ +Assuming you copied them into plugins folder; the structure in your project should be somewhat like this: + +``` +.\Project-root ++-- \plugins* +| +-- \fontawesome* +| | +-- \css +| | +-- \js +| | +-- \webfonts +| | +| +-- \bootstrap* +| | +-- \css +| | +-- \js +| | +| +-- \fb-formvalidator* +| | +-- \css +| | +-- \fonts +| | +-- \js +| |... ++-- index.html +|... +``` + +\ +Now all that is left is to add them into your document as so: + +```html + + + + + Title + + + + + + + + + + + + + + + + + + + + + + + + +``` + +> ### Note: +> #### To avoid errors: +> - The `fusion.form.validator.css` must come after `bootstrap css`, and `fontawesome css`. +> - The same goes for the `fusion.form.validator.js`, it must come after `jQuery js (If available)`, `bootstrap js`, and `fusion.form.util.js`. + +## Usage + +--- + +*Firstly, ensure the stylesheets and scripts are linked in the correct hierarchy as in the above example. If you have problems getting it correctly, just copy the code in the example above and edit.* + +Out of the box, Fusion Form Validator ships with `init.js` file, so you can initialize, configure, and use the fusion form validator without messing up your other JS codes.\ +**N.B:** You can still use the validator in another JS file. + +[comment]: <> (The Validator has already been initialized in `init.js` for all forms; with default configuration out of the box) + +To initialize and configure the validator on a form, you need an instance of the form.\ +A utility function is available for getting elements. Other methods could still be used too. + +Built-in function `$el(selector)` can be used to fetch an element or fetch elements. The `selector` argument is either the elements tag name, or a CSS selector `eg. '#login-form'` as a string. +### Initializing: +The form elements must follow the below structure\ +Assuming the form has id `login-form` i.e. + +```html + +
+
+
+ +
+ + +
+
+ + +
+
+ +
+
+ +
+ + +
+
+ + +
+
+ +
+ + +
+
+ + Please Wait... +
+
+
+
+
+``` + +\ +Instantiating and initializing the validator: + +```javascript +// Instantiate the Validator: + +// Using Built-in function +const validator = $el('#login-form').FBValidator(form_group); + +// Using jQuery +const validator = $('#login-form').FBValidator(form_group); + +// Using Vanilla JS +const validator = document.querySelector('#login-form').FBValidator(form_group); +// or... +const validator = document.getElementById('login-form').FBValidator(form_group); + + +// Configure the validator: An Object (KeyValue Pair) of options. +// Available config options in next section. +validator.validationConfig = { + showPassword: true, + validateEmail: true, + validatePassword: true +} + +validator.validationIcons = { + validIcon: '', + invalidIcon: '' +} + +// initialize the validator on the form. +validator.initValidation(); +``` + +> ### Available Config Options: +> #### Regular Expressions `regExp` config options; For validating associated form fields using given Regular Expression. +> +> | Key | Configurable Values | Default Value | Description | +> | ------------ | ----------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +> | _name_ | **_RegExp string_** | `'/^([a-zA-Z]{2,255})(\s[a-zA-Z]{2,255}){1,2}$/gi'` | RegExp string used to validate a `name` field
if `validateName` option is set to `true` | +> | _username_ | **_RegExp string_** | `'/^[a-zA-Z]+([_]?[a-zA-Z]){2,255}$/gi'` | RegExp string used to validate a `username` field
if `validateUsername` option is set to `true` | +> | _email_ | **_RegExp string_** | `'/^\w+([.-]?\w+)*@\w+([.-]?\w{2,3})*(\.\w{2,3})$/gi'` | RegExp string used to validate a `email` field
if `validateEmail` option is set to `true` | +> | _phone_ | **_RegExp string_** | `'/^(\+\d{1,3}?\s)(\(\d{3}\)\s)?(\d+\s)*(\d{2,3}-?\d+)+$/g'` | RegExp string used to validate a `phone` field
if `validatePhone` option is set to `true` | +> | _cardCVV_ | **_RegExp string_** | `'/[0-9]{3,4}$/gi'` | RegExp string used to validate a `card cvv` field
if `validateCard` option is set to `true` | +> | _cardNumber_ | **_RegExp string_** | `'/^[0-9]+$/gi'` | RegExp string used to validate a `card number` field
if `validateCard` option is set to `true` | +> +> These configuration options are accessible via the `validator.regExpConfig` and can be set using the syntax: +> ```javascript +> validator.regExpConfig = { +> name: 'value', +> email: 'value', +> phone: 'value', +> } +> ``` +> +>
+> +> #### Validation Icons `validationIcons` config options; Displayed validation icons. +> +> | Key | Configurable Values | Default Value | Description | +> | --------------------- | ----------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +> | _validIcon_ | **_HTML string_** | `''` | HTML string to show valid icon (tick or check) when a field is correctly filled. | +> | _invalidIcon_ | **_HTML string_** | `''` | HTML string to show invalid icon (times or exclamation) when a field has error. | +> | _passwordTogglerIcon_ | **_HTML string_** | `''` | HTML string to show a toggler icon for the password field. | +> +> These configuration options are accessible via the `validator.validationIcons` and can be set using the syntax: +> ```javascript +> validator.validationIcons = { +> validIcon: 'value', +> invalidIcon: 'value', +> passwordTogglerIcon: 'value', +> } +> ``` +> +>
+> +> #### Field Validation `validationConfig` config options; For toggling validation state of form field elements. +> +> | Key | Configurable Values | Default Value | Description | +> | --------------------- | ------------------------------------------ | --------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +> | _showPassword_ | **_boolean
`true` or `false`_** | `true` | boolean to toggle showing the password type toggler icon. | +> | _validateCard_ | **_boolean
`true` or `false`_** | `false` | boolean to toggle Card Number and CVV field validation. | +> | _validateName_ | **_boolean
`true` or `false`_** | `false` | boolean to toggle Name field validation. | +> | _validateEmail_ | **_boolean
`true` or `false`_** | `false` | boolean to toggle Email field validation. | +> | _validatePhone_ | **_boolean
`true` or `false`_** | `false` | boolean to toggle Phone Number field validation. | +> | _validatePassword_ | **_boolean
`true` or `false`_** | `true` | boolean to toggle Password field validation
(***Mostly used if there is a password confirmation field***). | +> | _validateUsername_ | **_boolean
`true` or `false`_** | `false` | boolean to toggle Username field validation. | +> | _nativeValidation_ | **_boolean
`true` or `false`_** | `false` | boolean to toggle Native HTML Validation on the form. | +> | _passwordId_ | **_string_** | `'password'` | String that matches the `id` of the `password field`. | +> | _passwordConfirmId_ | **_string_** | `'password_confirmation'` | String that matches the `id` of the `confirm password field`. | +> +> These configuration options are accessible via the `validator.validationConfig` and can be set using the syntax: +> ```javascript +> validator.validationConfig = { +> showPassword: value, +> validateName: value, +> validateEmail: value, +> validatePassword: value, +> passwordConfirmId: 'value (e.g. confirm_password)' +> } +> ``` + +## About + +--- + +Fusion form validator is an easy-to-use JS plugin for front-end form validation and miscellaneous utilities which requires little or no knowledge of JavaScript. Read through this documentation on how to set it up, and you're ready. It's fun to use and hassle-free. + +## Creator + +--- + +### [Bien Nwinate](https://github.com/Bien-Glitch) + +- https://twitter.com/nwinate +- https://www.linkedin.com/in/nwinate-bien-609ab9175/ +- https://www.facebook.com/moses.bien +- Team member: + - [Loop DevOps LLC](https://github.com/officialLoopDevOps) + - [ScaletFox ltd](https://github.com/scaletfoxltd) + - [Vorldline Team](https://github.com/Vorldline) + +## Acknowledgement + +--- + +Thanks to God Almighty for making this project a possible.\ +Also a huge thanks to: + +- [ScaletFox ltd](https://github.com/scaletfoxltd) +- [Victor](https://github.com/echovick) +- [Omotayo](https://github.com/omotayosam) +- And many others for their huge support + +## Feedback + +--- + +If you discover a vulnerability or bug within the Fusion Form Validator, or have an improvement,\ +Please [open an issue on the Github page](https://github.com/Bien-Glitch/fusion.form.validator/issues) or send an e-mail to Bien Nwinate via [fusionboltinc@gmail.com](mailto:fusionboltinc@gmail.com).\ +All issues will be promptly addressed. + +## Contact + +--- + +- E-Mail: [fusionboltinc@gmail.com](mailto:fusionboltinc@gmail.com) +- Whatsapp DM: +234 815 744 9189 diff --git a/index.html b/index.html index d47c579..74b9485 100644 --- a/index.html +++ b/index.html @@ -59,7 +59,8 @@

Test Form

- + diff --git a/src/js/fusion.form.util.js b/src/js/fusion.form.util.js index bdc4099..0ac58dc 100755 --- a/src/js/fusion.form.util.js +++ b/src/js/fusion.form.util.js @@ -26,10 +26,6 @@ let valid_right, errorCount = {}, paddingMultipliers = {}; - -const newBsAlert = (element) => new bootstrap.Alert(element); -const newBsModal = (element, options) => new bootstrap.Modal(element, options); - const alert_d = 'alert-danger'; const alert_i = 'alert-info'; const alert_s = 'alert-success'; @@ -43,37 +39,14 @@ const fa_info = 'fa-info'; const fa_info_c = 'fa-info-circle'; const fa_wifi_s = 'fa-wifi-slash'; -window.formatNumber = (number) => number.toLocaleString('en-US', {minimumFractionDigits: 2}); - /** - * - * @param show {NodeList|HTMLElement|[HTMLElement]} - * @param hide {NodeList|HTMLElement|[HTMLElement]} - * @param target {NodeList|HTMLElement|Object|Array} - * @param showIcon {boolean} - */ -window.toggleValidationIcon = ({show, hide}, target, showIcon) => { - if (showIcon) { - hide.fadeout(); - target.addValidationPadding(); - show.touchCssValue({right: valid_right}).fadein() - } else - target.removeValidationPadding(); -} - -/** - * - * @param value {string} - * @returns {string} + * ---------------------------------------------------------- + * (**Utility Methods**) + * ---------------------------------------------------------- */ -window.spaceToComma = (value) => { - return value.trim().split(/[ ,]+/g).filter((val) => { - return val !== ''; - }).join(', '); -}; /** - * Validate the given form field element + * Validate the given form field element. * * @param context {HTMLElement|[HTMLElement]|undefined} * @param message {string|null} @@ -121,7 +94,7 @@ Object.prototype.validate = function ({context, message = null, isPassword = fal } /** - * Check if the form field element should be validated + * Check if the form field element should be validated. * * @returns {boolean|boolean} */ @@ -132,7 +105,7 @@ Object.prototype.needsValidation = function () { } /** - * Set CSS styles to the given element using KeyValue Pairs + * Set CSS styles to the given element using KeyValue Pairs. * * @param keyValuePair {Object} * @returns {[HTMLElement]} @@ -146,7 +119,7 @@ Object.prototype.touchCssValue = function (keyValuePair) { } /** - * Get CSS style Value + * Get CSS style Value. * * @param property {string} * @returns {string|undefined} @@ -162,7 +135,7 @@ Object.prototype.cssProperty = function () { } /** - * Add class to the elements' class list + * Add class to the elements' class list. * * @param className {string} * @returns {[HTMLElement]} @@ -175,7 +148,7 @@ Object.prototype.classListAdd = function (className) { } /** - * Remove class from the elements' class list + * Remove class from the elements' class list. * * @param className {string} * @returns {[HTMLElement]} @@ -188,7 +161,7 @@ Object.prototype.classListRemove = function (className) { } /** - * Check if element has given class + * Check if element has given class. * * @param className {string} * @returns {boolean|undefined} @@ -201,7 +174,7 @@ Object.prototype.includesClass = function (className) { } /** - * Adds padding to the right of the element via the {padding_right} variable + * Adds padding to the right of the element via the {padding_right} variable. * * @returns {[HTMLElement]} */ @@ -214,7 +187,7 @@ Object.prototype.addValidationPadding = function () { } /** - * Resets the value of the padding-right CSS property to the value of the padding-left CSS property of the element + * Resets the value of the padding-right CSS property to the value of the padding-left CSS property of the element. * * @returns {[HTMLElement]} */ @@ -228,7 +201,8 @@ Object.prototype.removeValidationPadding = function () { /** * Checks if the target element has the given element. - * Returns an array of the element if true else an empty array is returned + * + * Returns an array of the element if true else an empty array is returned. * * @param element {NodeList|HTMLElement|[HTMLElement]} * @returns {*[]} @@ -246,7 +220,8 @@ Object.prototype.nodeContains = function (element) { /** * Returns the Previous sibling of the target element. - * Returns the sibling that matches the selector if the selector is given else the direct previous sibling is returned + * + * Returns the sibling that matches the selector if the selector is given else the direct previous sibling is returned. * * @param selector * @returns {HTMLElement|Element|*} @@ -271,6 +246,7 @@ Object.prototype.previousSiblings = function (selector) { /** * Returns an array of the elements siblings. + * * An empty array is returned if there are no siblings. * * @returns {*[]} @@ -285,7 +261,7 @@ Object.prototype.siblings = function () { } /** - * Checks the status of given CSS Pseudo selector on the target element + * Checks the status of given CSS Pseudo selector on the target element. * * @param selector * @returns {boolean} @@ -297,7 +273,7 @@ Object.prototype.selectorMatches = function (selector) { } /** - * Checks if the mouse cursor is over the element + * Checks if the mouse cursor is over the element. * * @returns {Promise} */ @@ -313,7 +289,7 @@ Object.prototype.mouseIsOver = async function () { } /** - * Checks if the given form field element is a Phone number field + * Checks if the given form field element is a Phone number field. * * @returns {boolean} */ @@ -326,7 +302,7 @@ Object.prototype.isPhoneField = function () { } /** - * Checks if the given form field element is a Password field + * Checks if the given form field element is a Password field. * * @returns {boolean} */ @@ -361,7 +337,7 @@ Object.prototype.regExpValidate = function ({regExp, context, message, customVal } /** - * Validates the given input field as an E-Mail field with the given RegExp + * Validates the given input field as an E-Mail field with the given RegExp. * * @param regExp {RegExp} * @param context {HTMLElement|[HTMLElement]|undefined} @@ -791,16 +767,15 @@ Object.prototype.upon = function (events, callback, option = false) { const target = (this.constructor.name.toUpperCase() === 'NODELIST' || this.constructor.name.toUpperCase() === 'S') ? Array.from(this) : (Array.isArray(this) ? this : [this]); target.forEach(element => { - if (typeof events === 'object') { - Object.keys(events).filter(evt => { - element.addEventListener(evt, (e) => handler.handleEvent({evt: e, prefix: 'on', callback: events[evt]}), option); - }) - } else + if (typeof events === 'object') + Object.keys(events).filter(evt => element.addEventListener(evt, (e) => handler.handleEvent({evt: e, prefix: 'on', callback: events[evt]}), option)); + else typeof callback === 'function' ? element.addEventListener(events, (e) => callback(e), option) : console.error('Listener undefined'); }); return target; } + /** * Displays validation message. * @@ -1048,6 +1023,7 @@ Object.prototype.disable = function (option = true) { /** * Load the given modal with a callback. + * * @param options {Object} * @param callback {function} * @returns {[HTMLElement]} @@ -1062,6 +1038,7 @@ Object.prototype.onModalLoad = function (options, callback) { /** * Dispose the given modal with a callback. + * * @param callback */ Object.prototype.onModalClose = function (callback) { @@ -1072,7 +1049,8 @@ Object.prototype.onModalClose = function (callback) { } /** - * Handle the submission of the target form using the fetch API (***https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API***) + * Handle the submission of the target form using the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) + * * Returns a promise which can be used to handle actions after response of the resource. * * @param uri {string} @@ -1162,7 +1140,8 @@ Object.prototype.handleFormSubmit = function ({uri = '', method = 'get', data = } /** - * Loads specified Page/HTML into the target element fro given URI. + * Loads specified Page/HTML into the target element from given URI. + * * If the selector parameter is specified the it will load the content of the specified element for the given URI. * * @param uri {string} @@ -1209,6 +1188,7 @@ Object.prototype.loadPageData = async function ({uri, selector = null, data = nu /** * Check if the target element has a scrollbar in the given direction. + * * Default direction is vertical. * * @param direction {string} @@ -1233,7 +1213,7 @@ Object.prototype.hasScrollBar = function (direction = 'vertical') { * @param form_group {string|selector} * @returns {FBFormValidate} */ -Object.prototype.initValidator = function (form_group) { +Object.prototype.FBValidator = function (form_group) { const target = ((this.constructor.name.toUpperCase() === 'NODELIST' || this.constructor.name.toUpperCase() === 'S') ? Array.from(this) : (Array.isArray(this) ? this : [this])); return new FBFormValidate(target, form_group); @@ -1282,9 +1262,10 @@ function $el(selector, context) { } } -// +// Misc Functions. window.$fb = { /** + * Perform a fetch request using the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). * * @param uri * @param method @@ -1325,9 +1306,12 @@ window.$fb = { }).catch(err => (typeof onError === 'function') && onError(err, status, statusText)); }, /** + * Toggle the disabled state (property) of button. + * + * Also toggle the button loader if available. * * @param buttonElement - * @param processIsDone + * @param processIsDone {boolean} */ toggleButtonState(buttonElement, processIsDone = false) { const target = ((buttonElement.constructor.name.toUpperCase() === 'NODELIST' || buttonElement.constructor.name.toUpperCase() === 'S') @@ -1347,6 +1331,9 @@ window.$fb = { } }, /** + * Manipulate the buttons state. + * + * (**N.B:** ***Depends on the toggleButtonState() function***). * * @param form * @param processIsDone @@ -1358,6 +1345,9 @@ window.$fb = { this.toggleButtonState(submitButton, processIsDone); }, /** + * Returns true if the string is a JSON string and can be parsed to a JSON Object. + * + * Returns false otherwise. * * @param JSONString * @returns {boolean} @@ -1372,16 +1362,86 @@ window.$fb = { } } + +/** + * Creates a new instance of Bootstrap Alert on the given element. + * + * @param element + * @returns {Alert} + */ +const newBsAlert = (element) => new bootstrap.Alert(element); + +/** + * Creates a new instance of Bootstrap Modal on the given element. + * + * @param element + * @param options + * @returns {Modal} + */ +const newBsModal = (element, options) => new bootstrap.Modal(element, options); + +/** + * + * @param number {number|string} + * @returns {string} + */ +window.formatNumber = (number) => number.toLocaleString('en-US', {minimumFractionDigits: 2}); + +/** + * + * @param show {NodeList|HTMLElement|[HTMLElement]} + * @param hide {NodeList|HTMLElement|[HTMLElement]} + * @param target {NodeList|HTMLElement|Object|Array} + * @param showIcon {boolean} + */ +window.toggleValidationIcon = ({show, hide}, target, showIcon) => { + if (showIcon) { + hide.fadeout(); + target.addValidationPadding(); + show.touchCssValue({right: valid_right}).fadein() + } else + target.removeValidationPadding(); +} + +/** + * + * @param value {string} + * @returns {string} + */ +window.spaceToComma = (value) => { + return value.trim().split(/[ ,]+/g).filter((val) => { + return val !== ''; + }).join(', '); +}; + +/** + * Multiply the values using the CSS calc() function + * + * @param pad1 {number|string} + * @param pad2 {number|string} + * @returns {string} + */ function multiplyPadding(pad1, pad2) { return `calc(${pad1} + ${pad2}px)`; } +/** + * Toggle Validation of the target element. + * + * @param element + * @param target + */ function checkValidate(element, target) { element[0].needsValidation() ? element.validate({context: target}) : element.removeValidationMessage({context: target, removeAlert: true}); } +/** + * Remove all corresponding validation elements when the targets' validation alert is closed. + * + * @param context + */ function onAlertClose(context) { $el('.alert').upon('close.bs.alert', function (e) { const target = e.currentTarget; @@ -1390,6 +1450,12 @@ function onAlertClose(context) { }); } +/** + * Checks the validity of the Card Number (Payment Card) using Luhn's Algorithm. + * + * @param numberInput {number|string} + * @returns {boolean} + */ function checkLuhn(numberInput) { const sumDigit = (c) => (c < 10) ? c : sumDigit(Math.trunc(c / 10) + (c % 10)); @@ -1400,6 +1466,12 @@ function checkLuhn(numberInput) { .reduce((acc, v) => acc + v) % 10 === 0; } +/** + * Parse the input and return the boolean equivalent. + * + * @param value + * @returns {boolean} + */ function parseBool(value) { switch (value) { case true: @@ -1415,40 +1487,114 @@ function parseBool(value) { } const handler = { + /** + * Handle incoming EventListener event from the upon() function. + * + * @param evt + * @param prefix + * @param callback + * @returns {false} + */ handleEvent({evt, prefix, callback}) { const handler = `${prefix}${evt.type}`; return typeof this[handler] === 'function' && this[handler](evt, callback); }, + /** + * Custom event from the handler. + * + * @param event + * @param callback + */ customEvent(event, callback) { typeof callback === 'function' && callback(event); }, + /** + * OnBlur Event + * + * @param element + * @param callback + */ onblur(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnClick Event + * + * @param element + * @param callback + */ onclick(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnFocus Event + * + * @param element + * @param callback + */ onfocus(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnKeyup Event + * + * @param element + * @param callback + */ onkeyup(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnKeydown Event + * + * @param element + * @param callback + */ onkeydown(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnInput Event + * + * @param element + * @param callback + */ oninput(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnMouseenter Event + * + * @param element + * @param callback + */ onmouseenter(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnMouseleave Event + * + * @param element + * @param callback + */ onmouseleave(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnChange Event + * + * @param element + * @param callback + */ onchange(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, + /** + * OnKeypress Event + * + * @param element + * @param callback + */ onkeypress(element, callback) { typeof callback === 'function' && this.customEvent(element, callback); }, diff --git a/src/js/fusion.form.validator.js b/src/js/fusion.form.validator.js index 934ae4e..cab9fd0 100755 --- a/src/js/fusion.form.validator.js +++ b/src/js/fusion.form.validator.js @@ -83,8 +83,8 @@ class FBBaseComponent { this._element = element } - static get DEFAULT_CONFIG() { - return this.prototype.config; + get DEFAULT_CONFIG() { + return this.config; } static get VERSION() { diff --git a/src/js/init.js b/src/js/init.js new file mode 100644 index 0000000..0bf0b1d --- /dev/null +++ b/src/js/init.js @@ -0,0 +1,34 @@ +/* +const forms = { + login: '#login-form', +}; + +Object.keys(forms).filter((form, idx) => { + let validator = {}, + formSelector = forms[form], + _form = $el(formSelector); + + if (_form.length) { + validator[form] = _form.FBValidator(form_group); + const formValidator = validator[form]; + + if (formValidator === validator.login) + formValidator.validationConfig = { + validatePassword: true + } + + formValidator.initValidation(); + console.log(formValidator.validationConfig); + } +}); +*/ + +// const validator = $el('#login-form').FBValidator(form_group); + +const validator = document.querySelector('#login-form').FBValidator(form_group); +validator.validationConfig = { + validateEmail: true, + validateName: true +} +validator.initValidation(); +console.log(validator, validator.config)