Magento 2: Date Format Validation Issue

In some cases you may want to show a date field in Magento. It is very important to validate the date input in the frontend side. For this, Magento has predefined validation rules. The most common rule for a date field will obviously be the validate-date rule.

However, this validate-date rule is not good enough to validate the date value especially with formats. In most cases, the rule will return a true value even though the date value does not have the correct date format.

Example Results

See the results of this rule for the cases below:

validator('validate-date', '24.12.1991', 'DD.MM.YYYY');  // = TRUE
validator('validate-date', '24.121991', 'DD.MM.YYYY');   // = TRUE
validator('validate-date', '24/12/1991', 'DD.MM.YYYY');  // = TRUE

Here the first line of code is the only correct date format. But, the rule will be passed for the wrong formats (3rd line in the above case) and even for a wrong value (see the second one). This is not what we need.

Why does validate-date not work as intended?

You will understand the problem if you look at the implementation of the rule. Internally, it uses a library called Moment.js to validate the date. See the rule definition below:

'validate-date': [
    function (value, params, additionalParams) {
        var test = moment(value, additionalParams.dateFormat);
        return utils.isEmptyNoTrim(value) || test.isValid();
    },
    $.mage.__('Please enter a valid date.')
]

So test variable above is a moment object. The rule performs the validation as test.isValid(). This expression will return TRUE in most cases, even if the format is completely different.

How can we fix this problem?

Fortunately, Moment has a solution to this problem. But, it is hidden in its documentation. Moment allows you to pass a third parameter that puts it in “Strict Mode”. It looks like this “Strict Mode” will solve our problem. Suppose we define a new rule to use it, like this:

'validate-strict-date': [
    function (value, params, additionalParams) {
        var test = moment(value, additionalParams.dateFormat, true);
        return utils.isEmptyNoTrim(value) || test.isValid();
    },
    $.mage.__('Please enter a valid date.')
]

For this new rule validate-strict-date, we will have the following results:

validator('validate-strict-date', '24.12.1991', 'DD.MM.YYYY');  // = TRUE
validator('validate-strict-date', '24.121991', 'DD.MM.YYYY');   // = FALSE
validator('validate-strict-date', '24/12/1991', 'DD.MM.YYYY');  // = FALSE

Nice! The results seem to be exactly what we want.

How Can I use this rule

For example, on the checkout page, suppose you have a date field and you want to check that the date format for this field is correct. In this case, you need to define the custom rule first. To do this:

File: app/code/<Namespace>/<Module>/view/frontend/requirejs-config.js

var config = {
    config: {
        mixins: {
            'Magento_Ui/js/lib/validation/validator': {
'<Namespace>_<Module>/js/ui/validation/validator/add-validate-strict-date-rule-mixin': true
            }
           
        }
    }
};

Now define the rule as follows:

File: `app/code/<Namespace>/<Module>/view/frontend/web/js/ui/validation/validator/add-validate-strict-date-rule-mixin.js`

define(['jquery', 'moment'], function($, moment) {
    'use strict';

    return function(validatorFunction) {
        validatorFunction.addRule(
            'validate-strict-date',
            function (value, params, additionalParams) {
                // Third parameter set with "true" makes moment in "strict mode"
                var test = moment(value, additionalParams.dateFormat, true);
                return test.isValid();
            },
            $.mage.__('Please enter a valid date.')
        );
        return validatorFunction;
    }
});

You are done. Now, if you add the validate-strict-date rule to your date input component, the rule will kick in and give you a red signal whenever there is an invalid formatted input value.

Rajeev K Tomy

Leave a Reply

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

Back to top