{ Hello Magento 2 }

解决 Magento 2 应用问题,更注重深度挖掘。(ง •̀_•́)ง

0%

Magento 2 add custom validation

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/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

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 Address

File: 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_attributecustomer_eav_attribute