7

Tried to add the following code to add validation for street, but it's not work. How to add the validation for street? Thanks.

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="shippingAddress"  xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shipping-address-fieldset" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="company" xsi:type="array">
                                                                    <item name="visible" xsi:type="boolean">false</item>
                                                                </item>
                                                                <item name="firstname" xsi:type="array">
                                                                    <item name="validation" xsi:type="array">
                                                                        <item name="validate-alpha" xsi:type="string">true</item>
                                                                    </item>
                                                                </item>
                                                                <item name="lastname" xsi:type="array">
                                                                    <item name="validation" xsi:type="array">
                                                                        <item name="validate-alpha" xsi:type="string">true</item>
                                                                    </item>
                                                                </item>
                                                                <item name="flat" xsi:type="array">
                                                                    <item name="validation" xsi:type="array">
                                                                        <item name="validate-alphanum-with-spaces" xsi:type="string">true</item>
                                                                    </item>
                                                                </item>
                                                                <item name="floor" xsi:type="array">
                                                                    <item name="validation" xsi:type="array">
                                                                        <item name="validate-alphanum-with-spaces" xsi:type="string">true</item>
                                                                    </item>
                                                                </item>
                                                                <item name="building" xsi:type="array">
                                                                    <item name="validation" xsi:type="array">
                                                                        <item name="validate-alphanum-with-spaces" xsi:type="string">true</item>
                                                                    </item>
                                                                </item>
                                                                <item name="street" xsi:type="array">
<!--                                                                    <item name="children" xsi:type="array">
                                                                        <item name="0" xsi:type="array">-->
                                                                            <item name="validation" xsi:type="array">
                                                                                <item name="validate-hk-address" xsi:type="string">true</item>
                                                                            </item>
<!--                                                                        </item>
                                                                        <item name="1" xsi:type="array">
                                                                            <item name="validation" xsi:type="array">
                                                                                <item name="validate-hk-address" xsi:type="string">true</item>
                                                                            </item>
                                                                        </item>
                                                                    </item>-->
                                                                </item>
                                                                <item name="city" xsi:type="array">
                                                                    <item name="validation" xsi:type="array">
                                                                        <item name="validate-hk-address" xsi:type="string">true</item>
                                                                    </item>
                                                                </item>
                                                                <item name="telephone" xsi:type="array">
                                                                    <item name="validation" xsi:type="array">
                                                                        <item name="validate-hk-phone-number" xsi:type="string">true</item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments> 
        </referenceBlock>
    </body>
</page>
9
  • can you show code for validation in rules.js? Jul 15, 2016 at 9:44
  • "validate-alphanum-with-spaces": [ function(value) { return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9 ]+$/.test(value); }, $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.') ],
    – Ricky.C
    Jul 15, 2016 at 9:50
  • it's original validation rule of magento.
    – Ricky.C
    Jul 15, 2016 at 9:50
  • plz share your xml file. Jul 15, 2016 at 9:51
  • updated content above
    – Ricky.C
    Jul 15, 2016 at 9:54

4 Answers 4

10

Firstly, Magento's validation for checkout_index_index.xml is not working properly so, you have to insert the rules while you replace the street fields.

You can do this by creating a plugin and insert the fields in Layout AfterProcessor.

`namespace/module/etc/frontend/di.xml`
...
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="rewrite-street" type="Namespace\Module\Model\Checkout\LayoutProcessorPlugin" sortOrder="10"/>
    </type>
...

And the LayoutProcessorPlugin should look like this:

namespace/module/Model/Checkout/LayoutProcessorPlugin

...

<?php

namespace Namespace\Module\Model\Checkout;

class LayoutProcessorPlugin
{
/**
 * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
 * @param array $jsLayout
 * @return array
 */

public function afterProcess(
    \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
    array  $jsLayout
) {
    $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
            ['shippingAddress']['children']['shipping-address-fieldset']['children']['street'] = [
        'component' => 'Magento_Ui/js/form/components/group',
        'label' => __('Street Address'),
        'required' => true,
        'dataScope' => 'shippingAddress.street',
        'provider' => 'checkoutProvider',
        'sortOrder' => 60,
        'type' => 'group',
        'additionalClasses' => 'street',
        'children' => [
                [
                'component' => 'Magento_Ui/js/form/element/abstract',
                'config' => [
                    'customScope' => 'shippingAddress',
                    'template' => 'ui/form/field',
                    'elementTmpl' => 'ui/form/element/input'
                ],
                'dataScope' => '0',
                'provider' => 'checkoutProvider',
                'validation' => ['required-entry' => true, "min_text_len‌​gth" => 1, "max_text_length" => 255],
            ],
                [
                'component' => 'Magento_Ui/js/form/element/abstract',
                'config' => [
                    'customScope' => 'shippingAddress',
                    'template' => 'ui/form/field',
                    'elementTmpl' => 'ui/form/element/input'
                ],
                'dataScope' => '1',
                'provider' => 'checkoutProvider',
                'validation' => ['required-entry' => false, "min_text_len‌​gth" => 1, "max_text_length" => 255],
            ]
        ]
    ];
    return $jsLayout;
    }
}

You can insert in validation array any validation rule you want.

2
  • Is this still the only way to add a validation to the street field? Or are validations for checkout_index_index working properly now? Feb 23, 2018 at 9:32
  • @KonstantinPatroev i have create same, and set default value for street and i want clear default value when a check box is clicked and it works, but after click in on check box street field gets blank and click on the button to move for payment validation is not working it step up with default value .can check the street field when default value is not set Jun 4, 2020 at 12:48
3

Creating a plugin and insert the fields in Layout AfterProcessor it is not the best way to solve that issue. The issue regarding the LayoutProcessorPlugin is first of all the layout xml (in this case the checkout_index_index.xml) is loaded afterward Magento is coping the all entries out of the attributes over the collected structure and in this case the LayoutProcessorPlugin is overriding the stuff.

So my Approach is to use the existing structure.

Here the (maybe cleaner) Approach This is a set up build in a Magento 2.2.8 Project

First of all, we need a mixin to validate the field.

Here is my mixin as an example based on the street field but it should be exactly the same for at least all of the address attributes:

Notice the JavaScript part is only necessary if you need a custom validation

define([
    'jquery',
    'jquery/validate'
], function ($) {
    "use strict";

    return function (validator) {
        validator.addRule(
            'validate-street-whitespace',
            function (value) {
                var pattern = /\s+\d+\s{0,}\w+$/;

                return value.match(pattern);
            },
            $.mage.__("Invalid street entry! Please add a whitespace between the street name and the house number!")
        );
        return validator;
    };
});

Here the setup for you're requirejs-config.js

var config = {
    config: {
        mixins: {
            'Magento_Ui/js/lib/validation/validator': {
                'js/validation-mixin': true // pathing depends on you're file location
            }
        }
    }
};

This is Javascript wise the complete setup. Instead of the LayoutProcessorPlugin you need to update the validate_rules entry in you're attribute table in my case it was the customer_eav_attribute my entry look's like this

{"max_text_length":255, "min_text_length": 1, "validate-street-whitespace": true}

To roll this change out to all of your systems programmatically I set up a patch. Notice: This part is a bit custom from my current project but it should provide you're the Idea how to set it up

<?php
namespace YourProject\Config\Setup\UpgradeData;

use Magento\Eav\Setup\EavSetup;
use Magento\Customer\Api\AddressMetadataInterface;
use Magento\Framework\Exception\LocalizedException;

class UpdateStreetAttribute0x0x72 extends EavSetup
{
    const STREET_ATTRIBUTE_CODE = 'street';

    /**
     * update street attribute
     * @throws LocalizedException
     */
    public function install()
    {
        $addressEntityTypeId = $this->getEntityTypeId(AddressMetadataInterface::ENTITY_TYPE_ADDRESS);
        $attributeData1 = $this->getAttribute($addressEntityTypeId, self::STREET_ATTRIBUTE_CODE);
        $attributeData1['validate_rules'] = '{"max_text_length":255, "min_text_length": 1, "validate-street-whitespace": true}';
        $this->updateAttribute($addressEntityTypeId, self::STREET_ATTRIBUTE_CODE, $attributeData1);

    }
}

Just as one more Notice adding a mixin for Magento_Ui/js/lib/validation/validator is only working in the Checkout.

1

Validation can be added by updating the admin configuration

Stores -> Configuration -> Attributes -> Customer Address -> Street

enter image description here

0

Below solution worked for me for city field in checkout. di.xml of custom module

<type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
    <plugin name="rewrite-street" type="Biztech\Override\Model\Checkout\LayoutProcessor" sortOrder="10"/>
</type>

Model/Checkout/LayoutProcessor.php

namespace custom\module\Model\Checkout;

use Magento\Checkout\Helper\Data;
use Magento\Framework\App\ObjectManager;
use Magento\Store\Api\StoreResolverInterface;

/**
 * Class LayoutProcessor
 */
class LayoutProcessor
{
    public function afterProcess(
    \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
    array  $jsLayout
) {
    $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
            ['shippingAddress']['children']['shipping-address-fieldset']['children']['city'] = [
        'required' => true,
    ];
    return $jsLayout;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.