Im trying to build a custom admin form (using ui components) for a custom entity. We can assume the entity is very simple(e.g. id,name)
One thing that i have hard time with, is populating the form with data.
For this purpose i wrote a custom data provider which looks something like this:
public function getData()
{
if (isset($this->loadedData)) {
return $this->loadedData;
}
$items = $this->collection->getItems();
/** @var Customer $customer */
foreach ($items as $faq) {
$this->loadedData[$faq->getId()] = $faq->getData();
}
$data = $this->getSession()->getFormData();
if (!empty($data)) {
$faqId = isset($data) ? $data : null;
$this->loadedData[$faqId] = $data;
$this->getSession()->unsFormData();
}
return $this->loadedData;
}
So the actual data are right under the id of the entity.
The ui component has a single fieldset with one field:
<fieldset name="general">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Conditions</item>
</item>
</argument>
<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">Label</item>
<item name="formElement" xsi:type="string">input</item>
<item name="dataScope" xsi:type="string">name</item>
<item name="source" xsi:type="string">general</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
</argument>
</field>
</fieldset>
The problem is, that the field never gets populated. Only way at the moment is to change stracture of the array returned by data provider:
$this->loadedData[$faq->getId()]['general'] = $faq->getData();
So the structure of the array has the same structure as fieldset -> field in the xml.
This seems to make some sense, however when i look how CMS module is defined for pages and blocks, it doesn't use the fieldset -> field hierarchy.
The data providers don't contain the fieldset key anywhere(or at least not from the getData) method, but the xml uses magical source 'block'.
For example for block
\Magento\Cms\Model\Block\DataProvider
public function getData()
{
if (isset($this->loadedData)) {
return $this->loadedData;
}
$items = $this->collection->getItems();
/** @var \Magento\Cms\Model\Block $block */
foreach ($items as $block) {
$this->loadedData[$block->getId()] = $block->getData();
}
$data = $this->dataPersistor->get('cms_block');
if (!empty($data)) {
$block = $this->collection->getNewEmptyItem();
$block->setData($data);
$this->loadedData[$block->getId()] = $block->getData();
$this->dataPersistor->clear('cms_block');
}
return $this->loadedData;
}
\Magento\Cms\view\ui_component\cms_block_form.xml
<fieldset name="general">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string"/>
</item>
</argument>
<field name="is_active">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">boolean</item>
<item name="label" xsi:type="string" translate="true">Enable Block</item>
<item name="formElement" xsi:type="string">checkbox</item>
<item name="source" xsi:type="string">block</item>
<item name="sortOrder" xsi:type="number">10</item>
<item name="dataScope" xsi:type="string">is_active</item>
<item name="prefer" xsi:type="string">toggle</item>
<item name="valueMap" xsi:type="array">
<item name="true" xsi:type="number">1</item>
<item name="false" xsi:type="number">0</item>
</item>
<item name="default" xsi:type="number">1</item>
</item>
</argument>
</field>
Where/How is this 'block' source created?
Do i really need to have the fieldset keys in data returned from the data provider?
Any help would be greatly appreciated.
Best Answer
Using dataPersistor to get Form data, thought you're using getSession
Save action
DataProvider
ui form xml