结帐表格-如何在一个类中包装多个元素-Magento 2


14

如何在div中包装两个结帐表单元素?

例如,假设我想将这些国家/地区和邮政编码/邮政编码字段包装在类别为的div中,该example-class怎么做?

在此处输入图片说明

我尝试过的

我试图通过将它们添加为的子代来实现这一点,<item name="shippingAddress" xsi:type="array">但这只会在前端导致错误。尽管我确实得到了一个空白文本输入,里面没有标签.example-class,但是前端还是有错误。

错误: Cannot read property 'indexedOptions' of undefined

这是我的快速尝试:

Magento_Checkout / web / template / shipping-address / form.html

<div id="shipping-new-address-form" class="fieldset address">
    <div class="testing">
        <!-- ko foreach: getRegion('example-class') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
    </div>
    <!-- ko foreach: getRegion('additional-fieldsets') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
    <!--/ko-->
</div>

checkout_index_index.xml

<item name="example-for-adding-class" xsi:type="array">
    <item name="component" xsi:type="string">uiComponent</item>
    <item name="config" xsi:type="array">
        <item name="deps" xsi:type="array">
            <item name="0" xsi:type="string">checkoutProvider</item>
        </item>
    </item>
    <item name="displayArea" xsi:type="string">example-class</item>
    <item name="children" xsi:type="array">
        <!-- The following items override configuration of corresponding address attributes -->
        <item name="region" xsi:type="array">
            <!-- Make region attribute invisible on frontend. Corresponding input element is created by region_id field -->
            <item name="visible" xsi:type="boolean">false</item>
        </item>
        <item name="region_id" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Ui/js/form/element/region</item>
            <item name="config" xsi:type="array">
                <item name="template" xsi:type="string">ui/form/field</item>
                <item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
                <item name="customEntry" xsi:type="string">shippingAddress.region</item>
            </item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
            <!-- Value of region_id field is filtered by the value of county_id attribute -->
            <item name="filterBy" xsi:type="array">
                <item name="target" xsi:type="string"><![CDATA[${ $.provider }:${ $.parentScope }.country_id]]></item>
                <item name="field" xsi:type="string">country_id</item>
            </item>
        </item>
        <item name="postcode" xsi:type="array">
            <!-- post-code field has custom UI component -->
            <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item>
            <item name="sortOrder" xsi:type="string">2</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="string">true</item>
            </item>
        </item>
        <item name="country_id" xsi:type="array">
            <item name="sortOrder" xsi:type="string">1</item>
        </item>
    </item>
</item>

必须有一种更简单的方法来执行此操作,或者我丢失了某些东西,或者这是过度工程的定义。在两个元素上添加一个div绝对不会如此困难。

Answers:


17

非常有趣的问题。让我回答有关Checkout实现的最后一个假设。由于您必须在1个文件中添加多个更改,因此可能有点过度设计。

该方法不需要在Magento 2核心模块中执行修改。

为了实现您的目标并将结帐送货地址字段包装到自定义元素中,应添加以下元素:

  1. 使用新的UI组件定义的自定义checkout_index_index.xml文件
  2. 带有自定义元素的新HTML模板
  3. 布局处理器插件
  4. 新插件的di.xml声明

Custom_Checkout \图\前端\布局\ 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="custom-field-group" xsi:type="array">
                                                                <item name="component" xsi:type="string">uiComponent</item>
                                                                <item name="sortOrder" xsi:type="string">0</item>
                                                                <item name="template" xsi:type="string">Custom_Checkout/checkout/field-group</item>
                                                                <item name="children" xsi:type="array">
                                                                    <item name="field-group" xsi:type="array">
                                                                        <item name="component" xsi:type="string">uiComponent</item>
                                                                        <item name="displayArea" xsi:type="string">field-group</item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </arguments>
    </referenceBlock>
</body>

在布局中,我们应该添加新的custom-field-group UI组件。该组件具有其自己的模板Custom_Checkout \ view \ web \ template \ checkout \ field-group.html,其中呈现了所有字段。此外,customfield-field-group组件的sortOrder节点的值为“ 0” 。它允许在声明为shipping-address-fieldset组件一部分的所有字段之前呈现组件。

另外,还有一个具有其自己的displayArea设置的字段组 UI组件。

Custom_Checkout \图\网络\模板\结账\现场group.html模板文件:

<div class="custom">
<!-- ko foreach: getRegion('field-group') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>

该模板允许呈现添加到字段组区域(也称为displayArea)中的所有组件。

自定义\结帐\插件\ AddressLayoutProcessor类文件:

namespace Custom\Checkout\Plugin;

use Magento\Checkout\Block\Checkout\LayoutProcessor;

/**
 * Class AddressLayoutProcessor
 */
class AddressLayoutProcessor
{
    /**
     * @param LayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */
    public function afterProcess(LayoutProcessor $subject, array $jsLayout)
    {
        $fieldGroup = &$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
            ['children']['shippingAddress']['children']['shipping-address-fieldset']
            ['children']['custom-field-group']['children']['field-group']['children'];

        $shippingAddressFields = &$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
            ['children']['shippingAddress']['children']['shipping-address-fieldset']['children'];

        $fieldGroup['country_id'] = $shippingAddressFields['country_id'];
        $fieldGroup['postcode'] = $shippingAddressFields['postcode'];

        $shippingAddressFields['country_id']['visible'] = false;
        $shippingAddressFields['postcode']['visible'] = false;

        return $jsLayout;
    }
}

该类负责将country_id邮政编码字段配置都复制到新创建的custom-field-group组件中。

一旦将字段分配给custom-field-group,则应将其标记为隐藏(visible = true),以避免在渲染过程中出现重复。由于其他依赖性(例如region.js文件)和送货地址处理机制,componentDisabled不应用于禁用country_id和邮政编码。

自定义\结帐\等\前端\ di.xml文件:

<?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="customFieldGroupPlugin" type="Custom\Checkout\Plugin\AddressLayoutProcessor"/>
    </type>
</config>

用于字段的插件方法发生了变化,因为应该使用完整的配置复制字段。如果在自定义模块中声明了布局处理器,则插件将捕获更改。

结果,country_idpostcode字段都以收货地址形式呈现,并包装到下面的自定义元素中(我为自定义 CSS类添加了几种样式以使其在表单中脱颖而出):

在此处输入图片说明

如果您还想修改帐单邮寄地址表单,则应更新Custom \ Checkout \ Plugin \ AddressLayoutProcessor类。您需要做的就是对帐单地址进行特定的付款方式处理,就像我们对收货地址字段一样。

乐意效劳!


太好了,谢谢!我永远都做不到,这很有趣,它如何要求后端工作。我纯粹是从有限元的角度来解决这个问题。如果几天之内没有人提出一种更简单的解决方案(我认为其他人正在研究这一问题),我将其标记为已接受。再次感谢。
本·克鲁克

优秀答案:)
Keyur Shah

太好了,非常感谢。这个对我有用。
Pratik Mehta

如果我想对新的帐单地址进行同样的更改,那么?
Pratik Mehta

1
如果您还想修改帐单地址表单,则应该更新Custom \ Checkout \ Plugin \ AddressLayoutProcessor类。您所要做的就是对特定付款方式的帐单地址执行与我们对收货地址字段相同的操作。
Max Pronko

2

这不是推荐的方法,它很简单但并不优雅:

应用/代码/供应商/模块/视图/前端/布局/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>
        <referenceContainer name="content">
          <block class="Vendor\Salesman\Block\Checkout\Index" name="custom_checkout" before="-" template="Vendor_Module::checkout/index.phtml"/>
        </referenceContainer>
    </body>
</page>

应用/代码/石灰/推销员/视图/前端/模板/结帐/index.phtml

<script>
  require([
      'jquery',
      'mage/mage'
  ], function($){
      $(document).ready(function () {
         //detect if the shipping form container loaded
         var existCondition = setInterval(function() {
            if ($('#shipping').length) {
              moveElement();
            }
         }, 100);

         function moveElement(){
             //get The field postcode and country
             var postcodeField = $("div[name='shippingAddress.postcode']");
             var countryField = $("div[name='shippingAddress.country_id']");
             // insert the wrapeer
             $( '<div class="wrapper"></div>' ).insertBefore( postcodeField);
             // move the fields to wrapper
             $(".wrapper").append(postcodeField);
             $(".wrapper").append(countryField);
         }
      });
    }
  });
</script>

我已经投票赞成,因为我相信它会起作用,但是我同意它不是很干净,除非没有更清洁的方法,否则我不会使用它。谢谢。
本·克鲁克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.