Magento 2 add custom validation

magento 2 的 validation 是基于jquery validate 插件的。

一般页面的 validation 使用方式

对于一般的 phtml 页面来说,我们可以通过如下方法进行验证:

方法一

通过 data-validate 属性

<input data-validate='{"required":true}'name="field1" id="field1" ... />

方法二

把规则名称放到 class 中去

<input class="input-text required" name="field3" id="field3" ... />
<input class="input-text required-entry" name="field3" id="field3" ... />

方法三

使用规则名作为元素属性

<input required="true" name="field2" id="field2" ... />

方法四

通过在 data-mage-init 中设置规则

<form ... data-mage-init='{
    "validation":{
        "rules": {
            "field4": {
                "required":true
            }
        }
    }
}'>

方法一和方法二很常见。

参考文档 Validate a custom form in Magento 2

既然是基于 jquery validate plugin 的,那么他的一些方法还是管用的,比如我想自定义错误信息。

<input data-validate='{"required":true}'name="field1" id="field1" data-msg-required="我是自定义的错误信息"... />

增加自定义的 validation

假设我想给 telephone 字段增加一个自定义的规则,那么对于这个页面,我可以这样做:

requirejs(['jquery'], function ($) {
    $.validator.addMethod(
        'phoneCN', function (value) {
            if(value.match(/^1\d{10}$/)){
                return true;
            } else {
                return false;
            }
        }, '请输入正确的手机号');

    $('#telephone').attr('data-validate', "{required:true, 'phoneCN':true}");
});

在这个页面上,我们增加一个新的规则 phoneCN 并且把这个规则加到元素的 data-validate 中去。

但是如果我希望把这个规则合并到全局中去,就像 required 规则一样,该怎么做呢?

增加全局的 validation

上面提到普通页面的用法,那么肯定是有不普通的页面了。是的,不普通的页面包括 checkout 页面和 Admin 后台。他们都是通过 Magento_Ui 这个模块来 render 这些组件的。

普通页面用到的 validation 主要是 mage/validationlib\web\mage\validation.js
其他页面用到的是 Magento_Ui/js/lib/validation/validator

下面我们就通过 mixins 将 phoneCN 规则加进去。

关于 Mixin ,参考这里 The Curious Case of Magento 2 Mixins

File: app\code\Vendor\PhoneCNValidate\view\base\requirejs-config.js

var config = {
    config: {
        mixins: {
            'mage/validation': {
                'Vendor_PhoneCNValidate/js/lib/mage/validation-mixin': true
            },
            'Magento_Ui/js/lib/validation/validator': {
                'Vendor_PhoneCNValidate/js/lib/mage/validator-mixin': true
            }
        }
    }
}

File: app\code\Vendor\PhoneCNValidate\view\base\web\js\lib\mage\validation-mixin.js

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

    return function () {
        $.validator.addMethod(
            'phoneCN',
            function (phoneNumber, element) {
                return this.optional(element) || phoneNumber.match(/^1\d{10}$/);
            },
            $.mage.__('Please specify a valid phone number')
        );
    }
});

File: app\code\Vendor\PhoneCNValidate\view\base\web\js\lib\mage\validator-mixin.js

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

    return function (validator) {
        validator.addRule(
            'phoneCN',
            function (value) {
                return value.match(/^1\d{10}$/);
            },
            $.mage.__('Please specify a valid phone number')
        );

        return validator;
    };
});

这样普通页面,通过上面的四种方法,就可以调用自定义的验证。

核心代码中并没有把 validate_rules (本文最后一部分会提到)中的值转化成表单控件的 class 名,参看vendor\magento\module-custom-attribute-management\Block\Form\Renderer\AbstractRenderer.php #135,所以我们需要自己修。

下面我们要说不普通的页面了。

checkout 页中加入自定义验证

比如给 checkout 的 address 的 telephone 加 phoneCN 验证

File: app\code\Vendor\PhoneCNValidate\view\frontend\layout\checkout_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" 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="telephone" xsi:type="array">
                                                                    <item name="validation" xsi:type="array">
                                                                        <item name="phoneCN" xsi:type="number">1</item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Admin 后台 Customer Address

File: app\code\Vendor\PhoneCNValidate\Setup\InstallData.php

<?php
/**
 * Copyright © Isobar Commerce, Inc. All rights reserved.
 */

namespace Vendor\PhoneCNValidate\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;


class InstallData implements InstallDataInterface
{
    protected $eavSetupFactory;

    public function __construct(
        \Magento\Eav\Setup\EavSetupFactory $eavSetupFactory
    ) {
        $this->eavSetupFactory = $eavSetupFactory;
    }

    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
        // work in admin backend
        // $eavSetup->updateAttribute('customer', 'telephone', 'validate_rules', '{"phoneCN":true}');
        $eavSetup->updateAttribute('customer_address', 'telephone', 'validate_rules', '{"phoneCN":true}');
    }
}

就是说后台的验证规则是和数据库中的记录相关的。

eav_attributecustomer_eav_attribute

发表评论

电子邮件地址不会被公开。 必填项已用*标注