Implementation of validation rules has already been covered in one of my previous posts, but being implemented in 5 different ways caught me a bit off guard! ๐
Recently, I was working on a task which included implementation of validation rules on an input field. On checkout, where else? ๐ While I was in the process of researching what is where and how to complete the task, I have stumbled upon the following five levels of how validation rules are parsed in the validation phase. Here is a snippet of how it looks like in /lib/web/jquery/jquery.validate.js
:
var data;
...
data = $.validator.normalizeRules(
$.extend(
{},
$.validator.metadataRules(element),
$.validator.classRules(element),
$.validator.attributeRules(element),
$.validator.dataRules(element),
$.validator.staticRules(element)
),
element );
Let’s briefly cover each entry and demonstrate what is the connection when used in markup. In order to clearly see the differences in implementation, I have used different validation rules on purpose.
Metadata Rules
Metadata validation rules are defined via data-validate
attribute (phoneUS):
<input id="field1" class="input-text" name="field1" type="text" value="phoneUS" data-validate="{ phoneUS: true }" />
Class Rules
Class-based validation rules are defined via class
attribute (time12h):
<input id="field2" class="input-text time12h" name="field2" type="text" value="time12h" />
Attribute Rules
Attribute-based validation rules are defined as rule name as attribute and “true” as its value (ipv4):
<input id="field3" class="input-text" name="field3" type="text" value="ipv4" ipv4="true" />
Data Rules
Data-based validation rules are defined as any “data” attribute, followed by the “rule” word and the actual rule ID, like the following (ipv6):
<input id="field4" class="input-text" name="field4" type="text" value="data-rule-ipv6" data-rule-ipv6="" />
Static Rules
Static-based validation rules are defined as part of “data-mage-init” attribute, which is defined on the form
itself (alphanumeric):
<form data-mage-init="{"validation":{ "rules": { "field5": { "alphanumeric": true } } }}">...</form>
Let’s see all of those rules in action. Here is the form with all of the fields on page load:
After submitting and validation, here is how the form looks like now:
As you can see on the screenshot, the validation rules are being applied and triggered correctly. However, there is a bug when parsing the attribute rules.
We all know how problematic variable types can be. Let’s create a mixin for this issue and fix it!
Register Your Mixin
Add a new entry in requirejs-config.js
in your theme and add the following code:
var config = {
config: {
mixins: {
'jquery/jquery.validate': {
'jquery/jquery.validate-mixin': true
}
}
},
};
Create the Mixin
Create the file jquery.validate-mixin.js
in the correct folder and add the following code:
define([
'mage/utils/wrapper',
'jquery'
], function (wrapper, $) {
'use strict';
return function () {
$.fn.validate = wrapper.wrapSuper($.fn.validate, function (options) {
this._super(options);
$.validator.attributeRules = wrapper.wrapSuper($.validator.attributeRules, function (element) {
var rules = {},
$element = $( element ),
type = element.getAttribute( "type" ),
method, value;
for ( method in $.validator.methods ) {
// Support for <input required="" type="text" /> in both html5 and older browsers
if ( method === "required" ) {
value = element.getAttribute( method );
// Some browsers return an empty string for the required attribute
// and non-HTML5 browsers might have required="" markup
if ( value === "" ) {
value = true;
}
// Force non-HTML5 browsers to return bool
value = !!value;
} else {
value = $element.attr( method );
// CONVERT STRING TO BOOLEAN
if (value === 'true') {
value = true
}
}
this.normalizeAttributeRule( rules, type, method, value );
}
// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
delete rules.maxlength;
}
return rules;
});
})
return $
};
})
With the correct implementation of the mixin, the value is now properly rendered as boolean value.
And that’s it, as simple as that! ๐
Thanks for reading my article, hope you liked it! If you have any questions, feel free to leave a comment or contact us. We’d be glad to help!
Until next time! ๐