Форма оформления заказа - Как обернуть несколько элементов в классе - Magento 2

14

Как обернуть два элемента формы оформления заказа в div?

Например, скажем, я хотел обернуть эти поля страны и почтового индекса в div с классом example-class, как бы я это сделал?

введите описание изображения здесь

Что я пробовал

Я пытался добиться этого, добавляя их в качестве потомков, <item name="shippingAddress" xsi:type="array">но это просто вызывает ошибки на веб-интерфейсе. Хотя я получил пустой текстовый ввод без метки внутри, .example-classна внешнем интерфейсе были ошибки.

Ошибка: Cannot read property 'indexedOptions' of undefined

Это моя быстрая попытка:

Magento_Checkout / веб / шаблон / груза-адрес / 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 над двумя элементами никогда не должно быть таким сложным.

Бен Крук
источник

Ответы:

17

Очень интересный вопрос Позвольте мне ответить на последнее предположение о реализации Checkout. Это может быть немного перегружено, так как вам нужно добавить более 1 изменения в 1 файл.

Подход не требует внесения изменений в основные модули Magento 2.

Для достижения вашей цели и упаковки полей адреса доставки в пользовательский элемент необходимо добавить следующие элементы:

  1. Пользовательский файл checkout_index_index.xml с новым определением компонента пользовательского интерфейса
  2. Новый шаблон HTML с пользовательским элементом
  3. Плагин Layout Processor
  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_Checkout \ view \ web \ template \ checkout \ field-group.html, в котором отображаются все поля. Кроме того, компонент группы пользовательских полей имеет значение «0» для узла sortOrder . Это позволяет визуализировать компонент перед всеми полями, объявленными как часть компонента shipping-address-fieldset .

Кроме того, существует компонент пользовательского интерфейса группы полей с собственным параметром displayArea .

В Custom_Checkout \ вид \ Web \ шаблон \ фотографии \ поля group.html файл шаблона:

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

Шаблон позволяет отображать все компоненты, добавленные в область группы полей (также известную как displayArea ).

Пользовательские \ 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;
    }
}

Этот класс отвечает за копирование конфигураций полей country_id и postcode во вновь созданный компонент группы пользовательских полей .

Поля, однажды назначенные группе пользовательских полей, должны быть помечены как скрытые (visible = true), чтобы избежать дублирования при рендеринге. ComponentDisabled не следует использовать для отключения country_id и почтового индекса из - за другие зависимости (например , region.js файл) и товаросопроводительного механизм обработки адресов.

Пользовательский \ Checkout \ и т.д. \ фронтенд \ 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>

Плагин подход, используемый для изменения полей, потому что поля должны быть скопированы с полной конфигурацией. В случае, если Layout Processor объявлен в пользовательском модуле, плагин будет ловить изменения.

В результате поля country_id и postcode отображаются в форме адреса доставки и переносятся в пользовательский элемент, как показано ниже (я добавил несколько стилей для того, чтобы пользовательский класс CSS выделялся в форме):

введите описание изображения здесь

Если вы также хотите внести изменения в форму адреса выставления счета, Custom \ Checkout \ Plugin \ AddressLayoutProcessor должен быть обновлен. Все, что вам нужно сделать, - это выполнить те же манипуляции с адресом выставления счета для конкретного способа оплаты, что и для полей адреса доставки.

Рад был помочь!

Макс Пронько
источник
Удивительно, спасибо! Я бы никогда не справился с этим, интересно, как это требует серверной работы. Я занимался этим с чисто FE-точки зрения. Если никто не придумает более простого решения в течение нескольких дней (как я думаю, некоторые другие люди в настоящее время смотрят на это), я отмечу его как принятый. Еще раз спасибо.
Бен Крук
Отличный ответ :)
Кейур Шах
Круто, спасибо большое. Меня устраивает.
Пратик Мехта
Если я хочу, чтобы то же самое изменение относилось к новому платежному адресу, тогда?
Пратик Мехта
1
Если вы также хотите внести изменения в форму адреса выставления счета, класс Custom \ Checkout \ Plugin \ AddressLayoutProcessor должен быть обновлен. Все, что вам нужно сделать, это выполнить те же манипуляции с адресом выставления счета для конкретного способа оплаты, что и для полей адреса доставки.
Макс Пронько
2

Это не рекомендуемый способ, он простой, но не элегантный:

Приложение / код / ​​Vendor / модуль / вид / интерфейс / расположение / 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>
Shell Suite
источник
Я проголосовал, так как уверен, что это сработает, но я согласен, что он не очень чистый, я бы не использовал его, если бы не было более чистого метода. Благодарю.
Бен Крук