6

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>
  • can you show code for validation in rules.js? – Bilal Usean Jul 15 '16 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 '16 at 9:50
  • it's original validation rule of magento. – Ricky.C Jul 15 '16 at 9:50
  • plz share your xml file. – Rakesh Jesadiya Jul 15 '16 at 9:51
  • updated content above – Ricky.C Jul 15 '16 at 9:54
6

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.

  • Is this still the only way to add a validation to the street field? Or are validations for checkout_index_index working properly now? – Konstantin Patroev Feb 23 '18 at 9:32
0

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.

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, privacy policy and cookie policy

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