With the 2.1 version, Magento migrated the admin product edit page from a mostly PHP-based version to a UI component one. And adding some fieldsets, fields, modal boxes, etc requires mainly XML tweaks. But let's say you want to generate fields dynamically...
This example is very simple for the sake of comprehension.
Configure the "container" with XML
First thing to do is to still use the UI component XML to create a fieldset that will then encompass your dynamic fields.
Just create a My/Module/view/adminhtml/ui_component/product_form.xml
file with this content:
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="my_fieldset" class="My\Module\Ui\Component\Form\Fieldset">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">More Product Links</item>
<item name="sortOrder" xsi:type="number">1000</item>
</item>
</argument>
</fieldset>
</form>
Dynamically create fields with PHP
As you can see in the previous XML snippet, the my_fieldset
fieldset has the My\Module\Ui\Component\Form\Fieldset
attached to it. This is where we will write our custom logic to inject fields into this fieldset.
So here is the My\Module\Ui\Component\Form\Fieldset
PHP class which, I think, don't need further explaination:
<?php
namespace My\Module\Ui\Component\Form;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentInterface;
use Magento\Ui\Component\Form\FieldFactory;
use Magento\Ui\Component\Form\Fieldset as BaseFieldset;
class Fieldset extends BaseFieldset
{
/**
* @var FieldFactory
*/
private $fieldFactory;
public function __construct(
ContextInterface $context,
array $components = [],
array $data = [],
FieldFactory $fieldFactory)
{
parent::__construct($context, $components, $data);
$this->fieldFactory = $fieldFactory;
}
/**
* Get components
*
* @return UiComponentInterface[]
*/
public function getChildComponents()
{
$fields = [
[
'label' => __('Field Label From Code'),
'value' => __('Field Value From Code'),
'formElement' => 'input',
],
[
'label' => __('Another Field Label From Code'),
'value' => __('Another Field Value From Code'),
'formElement' => 'input',
],
[
'label' => __('Yet Another Field Label From Code'),
'value' => __('Yet Another Field Value From Code'),
'formElement' => 'input',
]
];
foreach ($fields as $k => $fieldConfig) {
$fieldInstance = $this->fieldFactory->create();
$name = 'my_dynamic_field_' . $k;
$fieldInstance->setData(
[
'config' => $fieldConfig,
'name' => $name
]
);
$fieldInstance->prepare();
$this->addComponent($name, $fieldInstance);
}
return parent::getChildComponents();
}
}