Many times in Module development there is some case we need to get dynamic data into system configuration. Magento 2 provides Dynamic Row UI-Component. Dynamic rows UI components provide the functionality to store the data as a collection of records. It provides functionality to add, edit and delete rows as many as needed. it offers a huge variety of UI components from fields. we can set many UI component fields in dynamic rows like textbox, dropdown, multiselect, etc.
Now we create a dynamic row with text, select and date field into system configuration.
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> <system> <tab id="test" translate="label" sortOrder="201"> <label>Test Date</label> </tab> <section id="test" translate="label" sortOrder="130" showInDefault="1" showInWebsite="1" showInStore="1"> <class>separator-top</class> <label>Test Dynamic Row Demo</label> <tab>test</tab> <resource>Dolphin_DynamicRowDemo::test</resource> <group id="general_setting" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label>General</label> <field id="fieldname" translate="label" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Dynamic Row</label> <backend_model>Dolphin\DynamicRowDemo\Block\Adminhtml\System\Config\ArraySerialized</backend_model> <frontend_model>Dolphin\DynamicRowDemo\Block\Adminhtml\System\Config\DynamicFieldData</frontend_model> </field> </group> </section> </system> </config>
<?php namespace Dolphin\DynamicRowDemo\Block\Adminhtml\System\Config; use Magento\Framework\App\Cache\TypeListInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Config\Value as ConfigValue; use Magento\Framework\Data\Collection\AbstractDb; use Magento\Framework\Model\Context; use Magento\Framework\Model\ResourceModel\AbstractResource; use Magento\Framework\Registry; use Magento\Framework\Serialize\SerializerInterface; class ArraySerialized extends ConfigValue { protected $serializer; public function __construct( SerializerInterface $serializer, Context $context, Registry $registry, ScopeConfigInterface $config, TypeListInterface $cacheTypeList, AbstractResource $resource = null, AbstractDb $resourceCollection = null, array $data = [] ) { $this->serializer = $serializer; parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); } public function beforeSave() { $value = $this->getValue(); if (isset($value['__empty'])) { unset($value['__empty']); } $encodedValue = $this->serializer->serialize($value); $this->setValue($encodedValue); } protected function _afterLoad() { $value = $this->getValue(); if ($value) { $decodedValue = $this->serializer->unserialize($value); $this->setValue($decodedValue); } } }
<?php namespace Dolphin\DynamicRowDemo\Block\Adminhtml\System\Config; use Dolphin\DynamicRowDemo\Block\Adminhtml\System\Config\Field\CustomColumn; use Magento\Backend\Block\Template\Context; use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray; use Magento\Framework\DataObject; use Magento\Framework\Registry; class DynamicFieldData extends AbstractFieldArray { private $holidaysRenderer; private $dateRenderer; private $selectOptions; public function __construct( Context $context, Registry $coreRegistry, array $data = [] ) { $this->_coreRegistry = $coreRegistry; parent::__construct($context, $data); } protected function _prepareToRender() { $this->addColumn( 'select_date', [ 'label' => __('Date'), 'id' => 'select_date', 'class' => 'daterecuring', 'style' => 'width:300px', ] ); $this->addColumn( 'date_title', [ 'label' => __('Content'), 'class' => 'required-entry', 'style' => 'width:300px', ] ); $this->addColumn( 'select_field', [ 'label' => __('Option'), 'renderer' => $this->getSelectFieldOptions(), ] ); $this->_addAfter = false; $this->_addButtonLabel = __('Add More'); } protected function _prepareArrayRow(DataObject $row): void { $options = []; $selectFieldData = $row->getSelectField(); if ($selectFieldData !== null) { $options['option_' . $this->getSelectFieldOptions()->calcOptionHash($selectFieldData)] = 'selected="selected"'; } $row->setData('option_extra_attrs', $options); } private function getSelectFieldOptions() { if (!$this->selectOptions) { $this->selectOptions = $this->getLayout()->createBlock( CustomColumn::class, '', ['data' => ['is_render_to_js_template' => true]] ); } return $this->selectOptions; } protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element) { $html = parent::_getElementHtml($element); $script = '<script type="text/javascript"> require(["jquery", "jquery/ui", "mage/calendar"], function (jq) { jq(function(){ function bindDatePicker() { setTimeout(function() { jq(".daterecuring").datepicker( { dateFormat: "mm/dd/yy" } ); }, 50); } bindDatePicker(); jq("button.action-add").on("click", function(e) { bindDatePicker(); }); }); }); </script>'; $html .= $script; return $html; } }
<?php namespace Dolphin\DynamicRowDemo\Block\Adminhtml\System\Config\Field; use Magento\Framework\View\Element\Html\Select; class CustomColumn extends Select { public function setInputName($value) { return $this->setName($value); } public function setInputId($value) { return $this->setId($value); } public function _toHtml() { if (!$this->getOptions()) { $this->setOptions($this->getSourceOptions()); } return parent::_toHtml(); } private function getSourceOptions() { return [ ['label' => 'Yes', 'value' => '1'], ['label' => 'No', 'value' => '0'], ]; } }
I hope this helps you. For any doubts regarding this topic, please write your doubts in the comments section.
In Magento
Apr 02, 2023
Do not miss a chance to grab exciting offers on Magento Development at Dolphin Web Solution. We are providing discounts on various Magento services this season. Go and grab yours today at our Magento Store.