Magento 2: Add Custom Address Validation In Checkout

Magento 2 has its own set of validations for the address fields in the checkout step. But sometimes you may want to add some custom validations in the different address fields. Some examples may be like limiting the character limit in the firstname and lastname of shipping and billing address.
Use cases:
Some ERP systems have certain limits on the length of fields that they can store. But Magento has no such limit on these fields. So while exporting the order data to the ERP you may face problems.
Fortunately, we can handle this problem in Magento 2 with some effort. We will start by creating a new module for this functionality.

Step 1: Create module registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Webspeaks_AddressRestriction',
    __DIR__
);

Step 2: Create module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Webspeaks_AddressRestriction" setup_version="1.0.0"></module>
        <sequence>
            <module name="Magento_Customer"/>
            <module name="Magento_Checkout"/>
        </sequence>
</config>

Step 3: Create etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="Webspeaks_AddressRestriction_Checkout" type="Webspeaks\AddressRestriction\Block\LayoutProcessor" sortOrder="100"/>
    </type>
</config>

Step 4.a: Adding validation to Shipping Address

Create the Webspeaks\AddressRestriction\Block\LayoutProcessor.php. LayoutProcessor.php is the main file where we will add our custom validations to the address fields. So in this file, we can add validations for shipping address as well as billing address.
We will add validations for different fields. Here is an example for adding length limit on firstname:

<?php
    ...
    $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
             ['shippingAddress']['children']['shipping-address-fieldset']
             ['children']['firstname']['validation']['max_text_length'] = 20;

As you can see we have added a max length limit of 20 characters in firstname in shipping address. The following snippet adds similar limits to various other fields in shipping address:

<?php
namespace Webspeaks\AddressRestriction\Block;

class LayoutProcessor
{
    /**
     * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */
    public function afterProcess(
       \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
       array $jsLayout
    ) {
        // Firstname
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']['children']['firstname']['validation']['max_text_length'] = 20;

        // Lastname
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']['children']['lastname']['validation']['max_text_length'] = 20;

        // Company name
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']['children']['company']['validation']['max_text_length'] = 31;

        // City
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']['children']['city']['validation']['max_text_length'] = 31;

        // Region
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']['children']['region']['validation']['max_text_length'] = 21;

        // Country
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']['children']['country_id']['validation']['max_text_length'] = 31;

        // Postcode
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']['children']['postcode']['validation']['max_text_length'] = 13;

        // Street address
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']
                ['children']['street']['children'][0]['validation']['max_text_length'] = 40;
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']
                ['children']['street']['children'][1]['validation']['max_text_length'] = 40;

        return $jsLayout;
    }
}

Step 4.b: Adding validation to Billing Address

Adding validation to the billing address is a bit different. Billing address depends on the payment methods available during checkout. A different set of billing address fields is loaded for each payment method. For example, if you have two payment methods “Check/Money Order” and “Purchase Order”, there will be two sets of billing addresses on the checkout page. When you select any payment method only the corresponding set of address fields will show.
So we will have to add validation to all payment methods that we expect on the page. To make it easy we can create an array of possible payment methods and run a foreach loop to add the validations as shown below:

<?php
    ...
    $payment_methods = ['purchaseorder', 'checkmo', 'sagepaysuiteform', 'sagepaysuitepaypal'];
    foreach ($payment_methods as $payment) {
        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children']
                [$payment.'-form']['children']['form-fields']['children']
                ['firstname']['validation']['max_text_length'] = 20;

        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children']
                [$payment.'-form']['children']['form-fields']['children']
                ['lastname']['validation']['max_text_length'] = 20;

        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children']
                [$payment.'-form']['children']['form-fields']['children']
                ['company']['validation']['max_text_length'] = 31;

        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children']
                [$payment.'-form']['children']['form-fields']['children']
                ['city']['validation']['max_text_length'] = 31;

        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children']
                [$payment.'-form']['children']['form-fields']['children']
                ['country_id']['validation']['max_text_length'] = 31;

        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children']
                [$payment.'-form']['children']['form-fields']['children']
                ['postcode']['validation']['max_text_length'] = 13;

        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children']
                [$payment.'-form']['children']['form-fields']['children']['street']['children'][0]['validation']['max_text_length'] = 40;
        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children']
                [$payment.'-form']['children']['form-fields']['children']['street']['children'][1]['validation']['max_text_length'] = 40;
    }

Now install the new module like:

php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy

Written by Arvind Bhardwaj

Arvind is a certified Magento 2 expert with more than 10 years of industry-wide experience.

Website: http://www.webspeaks.in/