checkout流程中的用户信息与地址信息表单是通过LayoutProcessor提供数据并利用前端的uiElement绘制表单元素,所以不能用传统的方法给表单元素追加验证器与行为。

验证器

vendor/magento/module-ui/view/base/web/js/lib/validation/rules.js
以上脚本就是uiElement的验证器集合,可以重写此脚本并追加新的验证器,假设我们添加名为validate-checkout-phone的验证器。

添加元素行为

以实现电话号码每三位隔一个空格的需求,需要写成ko组件,并改写element模板。

先编写KO组件

define(['jquery','ko'], function($, ko) {
    ko.bindingHandlers.phone = {
        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            if(element.tagName == 'INPUT') {
                $(element).on('keyup', function(e){
                    if(e.keyCode >= 48 && e.keyCode <=90 && this.value) {
                        var _value = this.value;
                        var charArr = _value.replace(/ /g, '').split('');
                        for(var i=1; i<charArr.length; i++) {
                            if(i % 3 == 0) {
                                charArr[i] = ' '+charArr[i];
                            }
                        }
                        this.value = charArr.join('');
                    }
                });
            }
        }
    };
}

触发行为的模板

由于KO组件需要用data-bind把组件绑定到元素上,所以需要替换原来的元素模板才能实现
app/design/frontend/<theme>/default/Magento_Ui/web/templates/form/element/phone.html

<input class="input-text" type="text" data-bind="
    phone: true,
    value: value,
    valueUpdate: 'keyup',
    hasFocus: focused,
    attr: {
        name: inputName,
        placeholder: placeholder,
        'aria-describedby': noticeId,
        id: uid,
        disabled: disabled
    }" />

查询表单元素数据

以上已经把验证器与动作器都写好了,就得把它们接上表单元素,要实现这一点需要先查得LayoutProcessor数据,我的做法是在 app/design/frontend/<theme>/default/Magento_Checkout/templates/onepage.phtml 里打印出jsLayout,就会查出以下数据:
验证器数据
图片描述

表单元素模板数据
图片描述

DI添加plugin

查出元素数据后才能知道目标数据的位置,因为jsLayout数据是个巨大的需要。有了数据后就可以编写出以下代码

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="checkout_change" type="Infinity\Checkout\Plugin\Magento\Checkout\Block\Checkout\LayoutProcessor" />
    </type>

</config>
namespace Infinity\Checkout\Plugin\Magento\Checkout\Block\Checkout;

class LayoutProcessor {
    public function afterProcess( \Magento\Checkout\Block\Checkout\LayoutProcessor $subject, $jsLayout )
    {
        // 接上验证器
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['telephone']['validation']['validate-checkout-phone'] = true;
        // 替换新模板
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['telephone']['config']['elementTmpl'] = 'ui/form/element/phone';
    }
}

猫之良品
2.5k 声望139 粉丝

资深Drupal, magento与Joomla


引用和评论

0 条评论