Magento 2 – Add Custom Validation Rules and Apply Them

javascriptjquerymagento2validation

I'm trying to modify some validation rules for the State input in shipping address. I want to add an error message if user selects 'Texas'.

I created a mixin for Magento_Ui/js/lib/validation/rules in requirejs-config.js

I can add a new rule called 'customTexasValidationRule' in the rules collection. However i don't know how to apply this rule to the select input.

I see that i can declare the rules in the select template at vendor/magento/module-ui/view/frontend/web/templates/form/element/select.html but i don't want to create a new template file for such a small task.

Is there any quick and easy way to add such a small custom validation in Magento 2?

Best Answer

I have figured out a way to accomplish this:

I added a mixin for Magento_Ui/js/lib/validation/validator:

define([
    'jquery'
], function($) {
    return function(validator) {
        validator.addRule(
            'custom-rule',
            function (value) {
                // Custom rule logics here
                return false;
            $.mage.__('Custom error message')
        );
        return validator;
    }
});

Then i added this to etc/frontend/di.xml, depending the modules you installed, you may have different LayoutProcessorProvider, or you may have to use Magento\Checkout\Block\Checkout\LayoutProcessor, see the link i mention at the bottom for more details, here i have a checkout module to modify my checkout flow called MyVendor\MyCheckoutModule so i have this:

<type name="MyVendor\MyCheckoutModule\Model\Layout\LayoutProcessorProvider">
    <arguments>
        <argument name="processors" xsi:type="array">
            <item name="additional-billing-address-validation" xsi:type="string">MyVendor\MyModule\Block\Checkout\LayoutProcessor\Billing\Addtional\Validation</item>
        </argument>
    </arguments>
</type>

Then i added this Validation.php file

<?php
namespace MyVendor\MyModule\Block\Checkout\LayoutProcessor\Billing\Additional;

use Magento\Checkout\Block\Checkout\LayoutProcessorInterface;

class Validation implements LayoutProcessorInterface
{
    public function process($jsLayout)
    {
        $jsLayout['components']['checkout']['children']['paymentMethod']['children']['billingAddress']
            ['children']['region_id']['validation']['custom-rule'] = 1;

        return $jsLayout;
    }
}

Clear caches and refresh, the validation is now working with my select input in the billing address form.

Note that the structure could be different in $jsLayout, as i'm having a module to modify the checkout process so my structure is not the same with stock magento 2 layout.

Big thanks to Add rule to rules.js Magento2 for leading me in the right direction

Related Topic