Deep Dive into Validation Rules

Deep Dive into Validation Rules

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:

Input fields on page load

After submitting and validation, here is how the form looks like now:

Input fields after validation

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.

Parsing issue - value is string, not boolean

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! 😀

Maaaaagic!

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! 🙂

You made it all the way down here so you must have enjoyed this post! You may also like:

What is Mage-OS and Why Did We Join? Tihomir Vranjes
, | 0

What is Mage-OS and Why Did We Join?

Moving the validation error message, this time globally Danijel Vrgoc
, | 0

Moving the validation error message, this time globally

How to generate SSH keys for Git authorization Hrvoje Ivancic
, | 21

How to generate SSH keys for Git authorization

2 comments

  1. Hello, there!:

    I think that the Attribute rules code does not contains the validation:

    “”

    Isn’t it missing the “ipv4=true” rule?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.