Hình thức thanh toán - Cách bọc nhiều yếu tố trong một lớp - Magento 2


14

Làm thế nào để bạn bọc hai yếu tố hình thức thanh toán bên trong một div?

Ví dụ: giả sử tôi muốn bọc các trường quốc gia và mã zip / mã bưu điện này trong một div với lớp example-class, tôi sẽ làm điều này như thế nào?

nhập mô tả hình ảnh ở đây

Những gì tôi đã cố gắng

Tôi đã cố gắng để đạt được điều này bằng cách thêm chúng khi <item name="shippingAddress" xsi:type="array">còn nhỏ nhưng điều đó chỉ gây ra lỗi trên frontend. Mặc dù tôi đã nhận được một đầu vào văn bản trống mà không có nhãn bên trong .example-classcó lỗi trên lối vào.

Lỗi: Cannot read property 'indexedOptions' of undefined

Đây là nỗ lực nhanh chóng của tôi:

Magento_Checkout / web / mẫu / địa chỉ giao hàng / 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>

kiểm tra_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>

Phải có một cách dễ dàng hơn để làm điều này, hoặc tôi đang thiếu một cái gì đó hoặc đây là định nghĩa của kỹ thuật quá mức. Thêm một div trên hai yếu tố sẽ không bao giờ khó khăn như vậy.

Câu trả lời:


17

Câu hỏi rất thú vị. Hãy để tôi trả lời giả định cuối cùng về việc triển khai Checkout. Nó có thể được thiết kế quá mức một chút vì bạn phải thêm nhiều hơn 1 thay đổi trong 1 tệp.

Cách tiếp cận không yêu cầu thực hiện sửa đổi trong các mô-đun lõi Magento 2.

Để đạt được mục tiêu của bạn và bọc các trường địa chỉ giao hàng thanh toán thành một yếu tố tùy chỉnh, cần thêm các yếu tố sau:

  1. Tệp checkout_index_index.xml tùy chỉnh với định nghĩa Thành phần UI mới
  2. Mẫu HTML mới với thành phần tùy chỉnh
  3. Plugin xử lý bố cục
  4. Khai báo di.xml cho plugin mới

Tệp Custom_Checkout \ 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="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>

Trong bố cục, chúng ta nên thêm Thành phần UI nhóm trường tùy chỉnh mới . Thành phần này có mẫu riêng Custom_Checkout \ view \ web \ template \ checkout \ field-group.html nơi tất cả các trường được hiển thị. Ngoài ra, thành phần nhóm trường tùy chỉnh có giá trị "0" cho nút sortOrder . Nó cho phép hiển thị thành phần trước khi tất cả các trường được khai báo là một phần của thành phần vận chuyển địa chỉ trường .

Ngoài ra, có Thành phần UI nhóm trường với cài đặt displayArea riêng .

Tệp mẫu Custom_Checkout \ view \ web \ template \ checkout \ field-group.html :

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

Mẫu cho phép hiển thị tất cả các thành phần được thêm vào khu vực nhóm trường (còn được gọi là displayArea ).

Tệp lớp tùy chỉnh \ Checkout \ Plugin \ 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;
    }
}

Lớp này chịu trách nhiệm sao chép cả cấu hình trường country_idmã bưu điện vào thành phần nhóm trường tùy chỉnh mới được tạo .

Các trường, một khi được gán cho nhóm trường tùy chỉnh phải được đánh dấu là ẩn (hiển thị = true) để tránh trùng lặp trong khi kết xuất. Không nên sử dụng thành phần Được kích hoạt để vô hiệu hóa country_id và mã bưu điện do các phụ thuộc khác (ví dụ: tệp area.js) và cơ chế xử lý địa chỉ giao hàng.

Tệp tùy chỉnh \ Checkout \ etc \ frontend \ 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>

Cách tiếp cận plugin được sử dụng cho các trường thay đổi vì các trường nên được sao chép với cấu hình hoàn chỉnh. Trong trường hợp Bộ xử lý bố trí được khai báo trong một mô-đun tùy chỉnh, plugin sẽ nắm bắt các thay đổi.

Kết quả là, cả hai trường country_idmã bưu điện được hiển thị trong biểu mẫu địa chỉ giao hàng và được gói vào phần tử tùy chỉnh như bên dưới (Tôi đã thêm một vài kiểu cho lớp CSS tùy chỉnh để nổi bật trong biểu mẫu):

nhập mô tả hình ảnh ở đây

Nếu bạn cũng muốn thực hiện sửa đổi đối với biểu mẫu địa chỉ thanh toán, lớp Custom \ Checkout \ Plugin \ addressLayoutProcessor sẽ được cập nhật. Tất cả bạn phải làm là thực hiện các thao tác tương tự với địa chỉ thanh toán cho phương thức thanh toán cụ thể như chúng tôi có cho các trường địa chỉ giao hàng.

Vui vẻ giúp đỡ!


Thật tuyệt vời, cảm ơn bạn! Tôi sẽ không bao giờ quản lý được điều đó, thật thú vị khi nó đòi hỏi công việc phụ trợ. Tôi đã giải quyết vấn đề này từ quan điểm hoàn toàn FE. Nếu không ai đưa ra giải pháp đơn giản hơn trong vài ngày (như tôi nghĩ một số người khác hiện đang xem xét điều này) tôi sẽ đánh dấu nó là chấp nhận. Cảm ơn một lần nữa.
Ben Crook

Câu trả lời tuyệt vời :)
Keyur Shah

Tuyệt vời, cảm ơn bạn rất nhiều. Nó làm việc cho tôi.
Pratik Mehta

Nếu tôi muốn thay đổi tương tự áp dụng cho địa chỉ thanh toán mới thì sao?
Pratik Mehta

1
Nếu bạn cũng muốn thực hiện sửa đổi đối với biểu mẫu địa chỉ thanh toán, lớp Custom \ Checkout \ Plugin \ addressLayoutProcessor sẽ được cập nhật. Tất cả bạn phải làm là thực hiện các thao tác tương tự với địa chỉ thanh toán cho phương thức thanh toán cụ thể như chúng tôi có cho các trường địa chỉ giao hàng.
Max Pronko

2

Đây không phải là một cách được đề xuất, nó đơn giản nhưng không thanh lịch:

ứng dụng / mã / Nhà cung cấp / Mô-đun / xem / 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>
        <referenceContainer name="content">
          <block class="Vendor\Salesman\Block\Checkout\Index" name="custom_checkout" before="-" template="Vendor_Module::checkout/index.phtml"/>
        </referenceContainer>
    </body>
</page>

ứng dụng / mã / Lime / Nhân viên bán hàng / xem / frontend / mẫu / thanh toán / 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>

Tôi đã tuyên bố rằng tôi tin rằng nó sẽ hoạt động nhưng tôi đồng ý rằng nó không sạch lắm, tôi sẽ không sử dụng nó trừ khi không có phương pháp sạch hơn. Cảm ơn.
Ben Crook
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.