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


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

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

enter image description here

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

Я пытался добиться этого, добавив их в качестве дочерних элементов <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 над двумя элементами никогда не должно быть таким сложным.

Author: Ben Crook, 2017-07-27

2 answers

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

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

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

  1. Обычай checkout_index_index.xml файл с новым определением компонента пользовательского интерфейса
  2. Новый HTML-шаблон с пользовательским элементом
  3. Плагин процессора компоновки
  4. В di.xml объявление для нового плагина

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>

В макет мы должны добавить новый компонент пользовательского интерфейса пользовательская группа полей . Компонент имеет свой собственный шаблон Custom_Checkout\view\web\template\checkout\field-group.html где отображаются все поля. Кроме того, компонент пользовательской группы полей имеет значение "0" для узла сортировщика. Это позволяет отображать компонент перед всеми полями, объявленными как часть компонента набор полей адреса доставки.

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

В Custom_Checkout\view\web\template\checkout\field-group.html файл шаблона:

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

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

Файл класса Пользовательский\Проверка\Плагин\Адресный обработчик:

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;
    }
}

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

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

Custom\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>

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

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

enter image description here

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

Рад помочь!

 18
Author: Max Pronko, 2017-11-10 11:30:24

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

App/code/Vendor/Module/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>
        <referenceContainer name="content">
          <block class="Vendor\Salesman\Block\Checkout\Index" name="custom_checkout" before="-" template="Vendor_Module::checkout/index.phtml"/>
        </referenceContainer>
    </body>
</page>

Приложение/код/Лайм/Продавец/просмотр/интерфейс/шаблоны/оформление заказа/индекс.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>
 2
Author: Shell Suite, 2017-11-10 11:49:19