magento 2 的 validation 是基于jquery validate 插件 的。
一般页面的 validation 使用方式对于一般的 phtml
页面来说,我们可以通过如下方法进行验证:
方法一通过 data-validate
属性
1 <input data-validate='{"required":true}'name="field1" id="field1" ... />
方法二把规则名称放到 class 中去
1 2 <input class="input-text required" name="field3" id="field3" ... /> <input class="input-text required-entry" name="field3" id="field3" ... />
方法三使用规则名作为元素属性
1 <input required="true" name="field2" id="field2" ... />
方法四通过在 data-mage-init
中设置规则
1 2 3 4 5 6 7 8 9 <form ... data-mage-init='{ "validation":{ "rules": { "field4": { "required":true } } } }'>
方法一和方法二很常见。 参考文档 Validate a custom form in Magento 2 既然是基于 jquery validate plugin 的,那么他的一些方法还是管用的,比如我想自定义错误信息。
1 <input data-validate='{"required":true}'name="field1" id="field1" data-msg-required="我是自定义的错误信息"... />
增加自定义的 validation假设我想给 telephone 字段增加一个自定义的规则,那么对于这个页面,我可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 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/validation
即 lib\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
1 2 3 4 5 6 7 8 9 10 11 12 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?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 AddressFile: app\code\Vendor\PhoneCNValidate\Setup\InstallData.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?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_attribute
和 customer_eav_attribute