Как создать формы администратора Magento 2


Справочная информация

Что такое компонент пользовательского интерфейса?

Ui Components используются для представления отдельных элементов пользовательского интерфейса, таких как таблицы, кнопки, формы и другие. Это простые и гибкие компоненты, предназначенные для рендеринга пользовательского интерфейса, эти компоненты отвечают за рендеринг фрагментов страницы и обеспечивают/поддерживают дополнительные взаимодействия компонентов JavaScript.

Компоненты пользовательского интерфейса реализованы в модуле Magento_UI. Чтобы использовать Ui Components в пользовательском модуле, необходимо добавить зависимость для модуля Magento_UI в файл composer.json модуля.

В Magento 2 основными компонентами пользовательского интерфейса являются формы и сетки списков, все остальные являются второстепенными. Основные компоненты объявляются в файлах макета страницы, а вторичные компоненты — в конфигурационных файлах экземпляров компонентов верхнего уровня.

Узнайте, как вставить ui_components в страницу в посте «Как создавать файлы макета Magento 2».

Форма

Формы используются для того, чтобы сделать доступными поля для ввода и/или редактирования сущности, и такие поля могут быть разделены на наборы полей (боковые вкладки), чтобы указать, какие поля относятся к данной области.


Код для создания формы

Поставщик данных

Это класс PHP, отвечающий за предоставление данных из базы данных и обеспечение их доступности через атрибут name. Интерфейс {Magento}{Frameworks}{Module}{EntityName}{DataProviderInterface должен быть реализован классом {Vendor}{Module}{UiComponent}{EntityName}{FormDataProvider для создания и возврата данных в форму страницы.

<?php

namespace {Vendor}{Module}UiComponent{EntityName};

use MagentoUiDataProviderAbstractDataProvider;
use {Vendor}{Module}ModelResourceModel{EntityName}CollectionFactory;
use {Vendor}{Module}ModelResourceModel{EntityName}Collection;
use {Vendor}{Module}Model{EntityName};

class FormDataProvider extends AbstractDataProvider
{
    private Collection $collection;
    private array $loadedData;

    public function __construct(
        string $name,
        string $primaryFieldName,
        string $requestFieldName,
        CollectionFactory $collectionFactory,
        array $meta = [],
        array $data = []
    ) {
        $this->collection = $collectionFactory->create();
        parent::__construct(
            $name,
            $primaryFieldName,
            $requestFieldName,
            $meta,
            $data
        );
    }

    public function getData(): array
    {
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }

        if (!$this->collection->getSize()) {
            return $this->loadedData = [];
        }

        if ($this->collection->getSize()) {
            /** @var {EntityName} $item */
            foreach ($this->collection->getItems() as $item) {
                $this->loadedData[$item->getId()] = $item->getData();
            }
        }

        return $this->loadedData;
    }
}
Войдите в полноэкранный режим Выход из полноэкранного режима

ui_component.xml

Файлы ui_components должны соответствовать структуре папок {Vendor}{Module}{area}{ui_components}{ui_component_name}.xml.

Путь к области может быть frontend или adminhtml, что определяет, где будет применяться шаблон. Для вставки шаблона в админ-панель Magento используется область adminhtml, а для вставки шаблона в визуальную часть магазина — область frontend (в этой области он используется не очень часто).

<?xml version="1.0"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">{ui_component}.{ui_component}_data_source</item>
        </item>
        <item name="label" xsi:type="string" translate="true">{Label}</item>
    </argument>

    <settings>
        <buttons>
            <button name="{button_name}" class="{Vendor}{Module}BlockAdminhtml{Directory}{ButtonClassName}"/>
        </buttons>
        <namespace>{ui_component}</namespace>
        <layout>
            <navContainerName>left</navContainerName>
            <type>tabs</type>
        </layout>
        <deps>
            <dep>{ui_component}.{ui_component}_data_source</dep>
        </deps>
    </settings>

    <dataSource name="{ui_component}_data_source">
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
        <settings>
            <validateUrl path="{route_id}/{controller_directory}/{controller_name}"/>
            <submitUrl path="{route_id}/{controller_directory}/{controller_name}"/>
        </settings>
        <aclResource>{Vendor}_{Module}::{parentResourceId}</aclResource>
        <dataProvider class="{Vendor}{Module}UiComponent{EntityName}FormDataProvider" name="{ui_component}_data_source">
            <settings>
                <requestFieldName>{id}</requestFieldName>
                <primaryFieldName>{entity_id}</primaryFieldName>
            </settings>
        </dataProvider>
    </dataSource>

    <fieldset name="{fieldset_name}">
        <settings>
            <disabled>{true/false}</disabled>
            <label>{Fieldset Label}</label>
            <visible>{true/false}</visible>
            <additionalClasses>
                <class name="{class-name}">{true/false}</class>
            </additionalClasses>
            <level>{integer}</level>
            <collapsible>{true/false}</collapsible>
            <opened>{true/false}</opened>
        </settings>
    </fieldset>
<form>
Войдите в полноэкранный режим Выход из полноэкранного режима

Узел <form> представляет компонент формы, который является набором полей, которые могут быть сгруппированы во вкладки и наборы полей.

Аргумент

Узел <argument> представляет собой произвольную структуру, которая объявляет конфигурацию компонента формы, включающую данные, используемые для инициализации объекта. Дочерний узел <item name="provider"> отвечает за передачу данных в узел <dataSource>. Значение этого элемента делится на две части (которые разделяет полная остановка), первое значение отвечает за указание имени компонента пользовательского интерфейса, а вторая часть отвечает за имя <dataSource>, который предназначен для обработки данных на сервере и заставляет компонент пользовательского интерфейса обрабатывать эти данные.

Настройки

Узел <settings> отвечает за настройку родительского узла <form>.

  • Узел <buttons>: отвечает за добавление кнопок в верхнее меню формы. Для каждой кнопки, которую вы хотите добавить, просто создайте дочерний узел <buttons> и заполните атрибут name для этого узла, который будет id этой кнопки. Чтобы настроить кнопку, просто создайте дочерние узлы (<label>, <url> и <class>).
  • Узел <namespace>: является узлом, отвечающим за идентификацию формы и передачу ее на back-end для выполнения действий (валидация, одобрение и т.д.).
  • Узел <layout>: отвечает за определение компоновки UI-компонента. Дочерний узел <type> указывает, где будут обслуживаться наборы полей. Узел <navContainerName> указывает, как будет выглядеть позиция вкладки в соответствии с атрибутом layout файла макета страницы.
  • Узел <deps>: должен иметь дочерний узел <dep> и иметь такое же значение, как <item name="provider">.

Источник данных

узел <dataSource> ссылается на класс, который отвечает за получение запрошенных данных и взаимодействие с компонентом пользовательского интерфейса (многие компоненты *UI требуют этот узел для своей работы).

Атрибут component="Magento_Ui/js/form/provider" используется для поставщика данных для формы в определенном формате, который разделяется между всеми компонентами пользовательского интерфейса в области действия компонента формы. Рекомендуется назвать атрибут name="{ui_component_name}_data_source".

  • Узел <settings>: отвечает за настройку родительского узла <dataSource> и в нем вы можете определить, какой контроллер будет отвечать за проверку данных формы через узел <validateUrl>, а узел <submitUrl> отвечает за определение того, какому контроллеру будут отправлены данные формы.
  • Узел <aclResource>: определяет, к какому ресурсу ACL привязан и сможет ли вошедший в систему пользователь получить доступ на основе своей роли пользователя, каждый пользователь будет ограничен выбранными ресурсами своей роли.
  • Узел <dataProvider>: является классом, отвечающим за обработку данных, возвращаемых из Data Provider, на этот класс нужно ссылаться через атрибут class, и можно определить класс, отвечающий за это выполнение, который должен расширять класс Magento
    DataProvider
    . Узел <dataProvider> имеет дочерний узел <settings>, где вы можете определить поле, которое будет использоваться в качестве id для грида в базе данных (через дочерний узел <primaryFieldName>) и для запроса (через дочерний узел <requestFieldName>).

Наборы полей

Компонент fieldset реализует контейнер для визуально сгруппированных элементов формы, таких как кнопки и поля формы. Узел <settings> отвечает за настройку набора полей и имеет следующие дочерние узлы:

Узел Описание Тип
отключено Начальное состояние компонента. При значении true пользователи не могут выполнять действия над элементом. bool
этикетка Метка для элемента в контексте. строка
видимый Видимость начального компонента. Если false, компонент будет скрыт. bool
additionalClasses Пользовательские классы, добавленные в блок на компоненте DOM. Объект (дочерний узел XML: {истина/ложь})
уровень Явно указывает уровень вложенности. int
разборный Включает/выключает функцию сворачивания для скрытия полей. bool
открыт Начальное расширенное состояние . Применяется, когда функциональность включена. bool

Поля

Атрибуты Описание Тип
класс Путь к PHP-классу, отвечающему за реализацию бэкенда компонента. строка
компонент Путь к .js-файлу компонента в терминах RequireJS. строка
displayArea Отображает компонент в месте, объявленном в макете. строка
elementTmpl Путь к шаблону .html определенного типа поля. строка
расширяет Расширяет конфигурацию указанного компонента. строка
formElement Элемент формы. тип
имя Индекс элемента в текущей области видимости коллекции, который будет использоваться для построения его уникального идентификатора. строка
провайдер Ссылка на поставщика данных компонента. строка
sortOrder Положение элемента. целое число
шаблон Путь к шаблону .html компонента. строка
отключено Начальное состояние компонента. Если установлено значение true, пользователи не могут выполнять действия над элементом. bool
этикетка Метка поля. строка
видимый Видимость начального компонента. bool
уведомления Массив уведомлений, которые должны быть связаны для каждого ключа с выбранным значением опции. массив
Вход
<field name="{input_name}" formElement="input" sortOrder="{integer}">
    <settings>
        <visible>{true/false}</visible>
        <label translate="true">{Label}</label>
    </settings>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

Текст
<field name="{text_name}" formElement="input" sortOrder="{integer}">
    <settings>
        <elementTmpl>ui/form/element/text</elementTmpl>
        <label translate="true">{Label Text}</label>
    </settings>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

Textarea
<field name="{textarea_name}" formElement="textarea" sortOrder="{integer}">
    <settings>
        <label translate="true">{Label Textarea}</label>
    </settings>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

Выберите
<field name="{select_name}" formElement="select" sortOrder="40">
    <settings>
        <label translate="true">{Label Select}</label>
    </settings>
    <formElements>
        <select>
            <settings>
                <options>
                    <option name="{option_name}" xsi:type="array">
                        <item name="value" xsi:type="string">{option_value}</item>
                        <item name="label" xsi:type="string">{Option Label}</item>
                    </option>
                </options>
                <caption translate="true">{-- Please Select --}</caption>
            </settings>
        </select>
    </formElements>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

Multiselect
<field name="{multiselect_name}" formElement="multiselect" sortOrder="{integer}">
    <settings>
        <dataType>text</dataType>
        <label translate="true">{Label Multiselect}</label>
        <dataScope>multiselect_name</dataScope>
    </settings>
    <formElements>
        <multiselect>
            <settings>
                <options>
                    <option name="{option_name}" xsi:type="array">
                        <item name="value" xsi:type="string">{option_value}</item>
                        <item name="label" xsi:type="string">{Option Label}</item>
                    </option>
                </options>
            </settings>
        </multiselect>
    </formElements>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

Флажок
<field name="{checkbox_name}" formElement="checkbox" sortOrder="{integer}">
    <settings>
        <label translate="true">{Label Checkbox}</label>
        <tooltip>
            <description translate="true">{Description}</description>
        </tooltip>
    </settings>
    <formElements>
        <checkbox>
            <settings>
                <prefer>checkbox</prefer>
                <valueMap>
                    <map name="false" xsi:type="boolean">false</map>
                    <map name="true" xsi:type="boolean">true</map>
                </valueMap>
            </settings>
        </checkbox>
    </formElements>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

<field name="{checkbox_toggle_name}" formElement="checkbox" sortOrder="{integer}">
    <settings>
        <label translate="true">{Label Checkbox}</label>
        <tooltip>
            <description translate="true">{Description}</description>
        </tooltip>
    </settings>
    <formElements>
        <checkbox>
            <settings>
                <prefer>toggle</prefer>
                <valueMap>
                    <map name="false" xsi:type="boolean">false</map>
                    <map name="true" xsi:type="boolean">true</map>
                </valueMap>
            </settings>
        </checkbox>
    </formElements>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

Радио
<field name="{radio_name}" formElement="checkbox" sortOrder="{integer}">
    <settings>
        <label translate="true">{Label Radio}</label>
        <tooltip>
            <description translate="true">{Description}</description>
        </tooltip>
    </settings>
    <formElements>
        <checkbox>
            <settings>
                <prefer>radio</prefer>
                <valueMap>
                    <map name="false" xsi:type="boolean">false</map>
                    <map name="true" xsi:type="boolean">true</map>
                </valueMap>
            </settings>
        </checkbox>
    </formElements>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

<radioset name="{radioset_name}" sortOrder="{integer}">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="additionalInfo" xsi:type="string">{Additional information}</item>
        </item>
    </argument>
    <settings>
        <label translate="true">{Label Radioset}</label>
        <options>
            <option name="{option_name}" xsi:type="array">
                <item name="value" xsi:type="string">{option_value}</item>
                <item name="label" xsi:type="string">{Option Label}</item>
            </option>
        </options>
    </settings>
</radioset>
Войдите в полноэкранный режим Выход из полноэкранного режима

Войдите в полноэкранный режим
<field name="{date_name}" formElement="date" sortOrder="{integer}">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="source" xsi:type="string">{source_name}</item>
        </item>
    </argument>
    <settings>
        <validation>
            <rule name="validate-date" xsi:type="boolean">{true/false}</rule>
        </validation>
        <dataType>{type}</dataType>
        <label translate="true">{Label Date}</label>
        <dataScope>{scope_name}</dataScope>
    </settings>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

ColorPicker
<colorPicker name="{colorspicker_name}" class="MagentoUiComponentFormElementColorPicker" component="Magento_Ui/js/form/element/color-picker" sortOrder="{integer}">
    <settings>
        <label translate="true">{Label Color}</label>
        <elementTmpl>ui/form/element/color-picker</elementTmpl>
        <colorFormat>rgb</colorFormat>
        <colorPickerMode>full</colorPickerMode>
        <dataScope>colors_filter</dataScope>
    </settings>
</colorPicker>
Войдите в полноэкранный режим Выход из полноэкранного режима

Файл
<file name="file_name" sortOrder="{integer}">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="label" xsi:type="string">{Label File}</item>
            <item name="visible" xsi:type="boolean">{true/false}</item>
            <item name="formElement" xsi:type="string">fileUploader</item>
            <item name="uploaderConfig" xsi:type="array">
                <item name="url" xsi:type="url" path="{router_id}/{controller_folder}/{controller_name}"/>
            </item>
        </item>
    </argument>
</file>
Войдите в полноэкранный режим Выход из полноэкранного режима

<field name="file_uploader_name" formElement="fileUploader" sortOrder="{integer}">
    <settings>
        <label translate="true">{Label File Uploader}</label>
    </settings>
    <formElements>
        <fileUploader>
            <settings>
                <uploaderConfig>
                    <param xsi:type="string" name="url">{router_id}/{controller_folder}/{controller_name}</param>
                </uploaderConfig>
            </settings>
        </fileUploader>
    </formElements>
</field>
Войдите в полноэкранный режим Выход из полноэкранного режима

HtmlContent

Компонент HtmlContent предоставляет возможность обработки и визуализации структуры макета или блока непосредственно в конфигурации компонента пользовательского интерфейса. Обработка и рендеринг выполняются на стороне сервера.

Структура макета внутри HtmlContent должна содержать только один блок верхнего уровня. Блок верхнего уровня может содержать столько дочерних блоков или контейнеров, сколько необходимо. Все блоки внутри HtmlContent интегрированы в макет, поэтому внешние блоки могут ссылаться на них и наоборот.

<htmlContent name="{html_component_name}">
    <block class="{Vendor}{Module}BlockAdminhtml{Directory}{ClassName}" name="{block_name}" template="{Vendor_Module}::{directory}/{file}.phtml">
        <arguments>
            <argument name="{argument_name}" xsi:type="{type}">{value}</argument>
        </arguments>
        <block class="{Vendor}{Module}BlockAdminhtml{Directory}{ClassName}" name="{block_name}" template="{Vendor_Module}::{directory}/{file}.phtml" />
    </block>
</htmlContent>
Войдите в полноэкранный режим Выход из полноэкранного режима

Кнопка меню

Этот класс отвечает за настройку кнопки, которая будет находиться в меню, для этого класс должен реализовать интерфейс MagentoFrameworksView и реализовать метод getButtonData(): array, возвращающий массив с настройками кнопки.

<?php

namespace {Vendor}{Module}BlockAdminhtml{Directory};

use MagentoFrameworkViewElementUiComponentControlButtonProviderInterface;
use MagentoFrameworkUrlInterface;

class {ButtonClassName} implements ButtonProviderInterface
{
    protected UrlInterface $urlBuilder;

    public function __construct(
        UrlInterface $urlBuilder
    ) {
        $this->urlBuilder = $urlBuilder;
    }

    public function getUrl(string $route = '', array $params = []): string
    {
        return $this->urlBuilder->getUrl($route, $params);
    }

    public function getButtonData(): array
    {
        return [
            'label' => __('{Label Button}'),
            'on_click' => sprintf("location.href = '%s';", $this->getUrl('{router_id}/{controller_directory}/{controller_name}')),
            'class' => '{class_name}',
            'sort_order' => {integer}
        ];
    }
}
Войдите в полноэкранный режим Выход из полноэкранного режима

Отделка

Значения между скобками ({test}) должны быть изменены в реализации кода.

Включение изменений

Удалите файлы, созданные при компиляции Magento, и запустите команду PHP для создания конфигурации инъекций зависимостей и всех недостающих классов, которые должны быть созданы (proxys, interceptors, etc), а также для очистки кэша всех процессов.

rm -rf var/generation/
rm -rf generated/
php bin/magento setup:di:compile
php bin/magento cache:clean
php bin/magento flush
Войдите в полноэкранный режим Выход из полноэкранного режима

Каталоги и файлы

Вот список каталогов и файлов, которые должны быть созданы.

- app/
  - code/
    - {Vendor}/
        - {Module}/
          - Block/
            - Adminhtml/
              - {ClassName}.php
          - etc/
            - di.xml
            - module.xml
          - Ui/
            - Component/
              - {EntityName}/
                - FormDataProvider.php
          - view/
            - adminhtml/
              - layout/
                - {router_id}_{controller_directory}_{controller_name}.xml
              - ui_component/
                - {ui_component}.xml
          - registration.php
          - composer.json
Войдите в полноэкранный режим Выход из полноэкранного режима

Оцените статью
Procodings.ru
Добавить комментарий