Как задать данные для поля в пользовательском интерфейсе формы
Есть ли правильный способ передачи данных (значение запроса) для формирования компонента пользовательского интерфейса?
Я попытался установить данные из dataProvider, определить в form-ui.xml но не работать. После завершения загрузки формы это поле должно быть заполнено данными (начальное значение)
/**
* Get data from provider and populate
* @param void
* @return array
*/
public function getData()
{
if (isset($this->loadedData)) {
return $this->loadedData;
}
if ($itemId)
$items = $this->collection->getItems();
$data = $this->dataPersistor->get('form_item');
if (!empty($data)) {
//Do something
} else {
//When form init without any data
// I want to setData for some field here
}
return $this->loadedData;
}
Мой текущий вопрос:
1 - Как правильно настроить данные для пользовательского интерфейса? Если мой путь неправильный, есть ли лучший способ сделать setdata для поля
2-сторонний вопрос: Как основная команда может заставить magento точно находить какая форма будет интерактивной. В форме старого способа мы можем определить оригинал формы с помощью тега формы htmlIdPrefix... и т.д., Но в новой форме я нигде не могу найти в uiform.xml для формы идентификатора конфигурации введите префикс формы.. Мне любопытно, как это работает
Будет здорово, если вы узнаете об этом
5 answers
В вашем custom_form.xml файл
<field name="your_field_id">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">{Vendorname}\{Modulename}\Model\Classname</item>
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Name label</item>
<item name="formElement" xsi:type="string">select</item>
<item name="source" xsi:type="string">[source_here]</item>
<item name="dataScope" xsi:type="string">your_field_id</item>
<item name="caption" xsi:type="string" translate="true">-- Please Select --</item>
</item>
</argument>
</field>
In above -- Please Select -- is set as default custom message for dropdown.
Где вы можете установить динамическую опцию выбора из этого класса,
{Vendorname}\{Modulename}\Model\Classname
используя метод tooptionarray().
В DataProvider.php файл,
<?php
namespace Yourmodule\Modulename\Model\Path;
class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
public function __construct(
\Magento\Framework\App\RequestInterface $request
) {
$this->_request = $request;
}
public function getData()
{
if (isset($this->loadedData)) {
return $this->loadedData;
}
$itemId = $this->_request->getParam('page_id');
if ( !empty($itemId) ) {
$items = $this->collection->getItems();
foreach ($items as $item) {
$this->loadedData[$item->getId()] = $item->getData();
}
$data = $this->dataPersistor->get('form_item');
if (!empty($data)) {
//Do something
$this->loadedData[$item->getId()] = $item->getData();
}
return $this->loadedData;
}
}
Еще один способ получения данных с помощью компонента пользовательского интерфейса.
Если вы хотите получить значение dafault из другого модуля, используя компонент пользовательского интерфейса
Добавьте это поле в свой custom_form.xml файл
<item name="options" xsi:type="object">{Vendorname}\{Modulename}\Ui\Component\Form\Element\DataProvider</item>
В DataProvider.php файл,
<?php
namespace {Vendorname}\{Modulename}\Ui\Component\Form\Element;
class DataProvider extends \Magento\Ui\Component\Form\Element\Input
{
/**
* Prepare component configuration
*
* @return void
*/
public function prepare()
{
parent::prepare();
$customValue = {Get Custom value};
$config = $this->getData('config');
if(isset($config['dataScope']) && $config['dataScope']=='your_field_id'){
$config['default']= $customValue;
$this->setData('config', (array)$config);
}
}
}
Вы можете создать пользовательский компонент js на основе того, который вы используете. Это довольно просто, учитывая пример компонента select. Мы используем исходную модель коллекции и форму пользовательского интерфейса наших модулей.
Пример компонента в xml-файле (пользовательский интерфейс):
<fieldset name="general">
<field name="methods">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">MageWorx\ShippingRules\Model\Config\Source\Methods</item>
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">text</item>
<item name="formElement" xsi:type="string">select</item>
<item name="component" xsi:type="string">MageWorx_ShippingRules/js/methods_select</item>
<item name="dataScope" xsi:type="string">methods</item>
<item name="source" xsi:type="string">mageworx_shippingrules_method_form</item>
</item>
</argument>
</field>
Простая исходная модель:
<?php
/**
* Copyright © 2016 MageWorx. All rights reserved.
* See LICENSE.txt for license details.
*/
namespace MageWorx\ShippingRules\Model\Config\Source;
class Methods implements \Magento\Framework\Option\ArrayInterface
{
/**
* @var \MageWorx\ShippingRules\Model\ResourceModel\Method\CollectionFactory
*/
protected $methodCollectionFactory;
/**
* MethodRatePrice constructor.
* @param \MageWorx\ShippingRules\Model\ResourceModel\Method\CollectionFactory $methodCollectionFactory
*/
public function __construct(
\MageWorx\ShippingRules\Model\ResourceModel\Method\CollectionFactory $methodCollectionFactory
) {
$this->methodCollectionFactory = $methodCollectionFactory;
}
/**
* @return array
*/
public function toOptionArray()
{
/** @var \MageWorx\ShippingRules\Model\ResourceModel\Method\Collection $collection */
$collection = $this->methodCollectionFactory->create();
$options = [
[
'value' => '',
'label' => __('Select value')
]
];
$options = array_merge($options, $collection->toOptionArray());
return $options;
}
}
И компонент js, унаследованный от выбора по умолчанию:
define([
'underscore',
'mageUtils',
'Magento_Ui/js/form/element/select'
], function (_, utils, Select) {
'use strict';
return Select.extend({
/**
* Extends instance with defaults, extends config with formatted values
* and options, and invokes initialize method of AbstractElement class.
* If instance's 'customEntry' property is set to true, calls 'initInput'
*/
initialize: function () {
this._super();
var parser = document.createElement('a');
parser.href = window.location.href;
var path = parser.pathname;
var clearPath = path.replace(/^(\/index\.php\/)|^\/|\/$/uig, "");
var params = clearPath.split("/");
var paramsObject = {};
for (var i = 0; i < params.length; i++) {
if (i < 4) {
delete params[i];
continue;
}
if (typeof params[i] == 'undefined' || typeof params[i + 1] == 'undefined') {
continue;
}
paramsObject[params[i]] = params[i + 1];
i++;
}
this.set('value', paramsObject.id);
return this;
}
});
});
Мы использовали базовый метод для инициализации компонента. Во-первых, мы назвали его родительский метод, который сделает всю основную работу. Затем мы проанализировали текущий адрес, разделили его на параметры и превратили в объект. Затем мы взяли необходимый параметр (идентификатор) и установили компонент значения, равный нашему параметру, из URL-адреса.
Это выглядит так в окне браузера:
И во время следующего сохранения:
Этот код может быть не идеальным, но он направит вас в правильном направлении. Если вы будете постарайтесь улучшить его, пожалуйста, напишите свой вариант.
Как из комментариев, так и из вопроса я понимаю, что проблема заключается в заполнении формы, когда новая сущность создается не при редактировании.
Ответ действительно прост.
Структурируйте свой URL-адрес создания следующим образом:
Www.website .[com|org|etc]/[администратор]/[имя пользователя]/[контроллер]/[действие]/[имя поля запроса]/0/[параметры..]
Затем при возврате $loadeddata от вашего поставщика данных.
/**
* @return array
*/
public function getData()
{
//Perform some check that is new action
$this->loadedData['0']['entity|fieldset-name] = $this-request->getParams()
return $this-loadedData;
}
Примите во внимание следующее:
По умолчанию в Magento2 идентификаторы сущностей начинаются с 1. Таким образом, 0 никогда не будет соответствовать существующему идентификатору сущности.
Решение не зависит от того, откуда берутся параметры. Я привел этот пример, потому что это было частью вопроса.
Надеюсь, это поможет.
Если я правильно понимаю, вам нужно установить значение по умолчанию для поля, которое создается с помощью компонентов пользовательского интерфейса.
Если это так, вы можете сделать это непосредственно из xml-файла компонентов пользовательского интерфейса.
Вы можете сделать это, установив опцию default
.
Вот пример:
<field name="name">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Name</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">[source_here]</item>
<item name="sortOrder" xsi:type="number">10</item>
<item name="dataScope" xsi:type="string">name</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
<item name="default" xsi:type="string">your defalt value here</item><!-- this will set a default value -->
</item>
</argument>
</field>
Проблема, вызванная неправильным вводом requestFieldName
.
В файле компонента вы находите тег dataSource
и проверяете, что primaryFieldName
является первичным ключом таблицы, а requestFieldName
- значением идентификатора параметра на вашем URL:
Пример: URL-адрес: http://127.0.0.1/domain.com/admin/moduleName/controlerName/edit/param_id/1
В файле вашего компонента: componentFileName_form.xml
В теге dataSource
:
<dataSource name="componentFileName_form_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Your_NameSpace\ModuleName\Model\ModelName\DataProvider</argument>
<argument name="name" xsi:type="string">componentFileName_form_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">table_id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="submit_url" xsi:type="url" path="multivendor/transactions/save"/>
</item>
</argument>
</argument>
<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>
</dataSource>
Пожалуйста, обратите внимание, что <argument name="primaryFieldName" xsi:type="string">table_id</argument>
является первичным ключом вашей таблицы, а <argument name="requestFieldName" xsi:type="string">param_id</argument>
- это параметр запроса по URL.