This post offers a programmatic solution to add a dynamic field in Magento 2 admin using system.xml file.
With the increasing use of E-commerce and business requirements that follows, a store owner may want to set dynamic values of a field based on certain conditions.
For example, the value of the order amount can change dynamically at an instance of time for different customer groups.
To configure such fields in Magento 2 admin panel, follow the below steps:
Solution to Add a Dynamic Field in Magento 2 Admin Using system.xml file:
Here, I have added Order Amount as a dynamic product.
If a merchant wishes to set the threshold based on the customer group, a merchant can easily set up using the Order Amount dynamic field.
Create registration.php file at app\code\Vendor\Module directory
1 2 3 4 5 | <?php use \Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Vendor_Module', __DIR__); |
Create module.xml file at app\code\Vendor\Module\etc directory
1 2 3 4 5 | <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_Module" setup_version="1.0.0"/> </config> |
Create system.xml file at app\code\Vendor\Module\etc\adminhtml directory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?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="extension_name" translate="label" class="extension_name" sortOrder="100"> <label></label> </tab> <section id="section_id" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Example</label> <tab>extension_name</tab> <resource>Vendor_Module::module_name</resource> <group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Configuration</label> <field id="enable" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Order Amount for Customer Group</label> <source_model>Magento\Config\Model\Config\Source\Enabledisable</source_model> </field> <field id="dynamic_field" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Order Amount</label> <backend_model>Vendor\Module\Block\Adminhtml\Config\Backend\ArraySerialized</backend_model> <frontend_model>Vendor\Module\Block\Adminhtml\DynamicField</frontend_model> </field> </group> </section> </system> </config> |
Create ArraySerialized.php file at app\code\Vendor\Module\Block\Adminhtml\Config\Backend directory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <?php namespace Vendor\Module\Block\Adminhtml\Config\Backend; 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(); 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); } } } |
Create DynamicField.php file at app\code\Vendor\Module\Block\Adminhtml directory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | <?php namespace Vendor\Module\Block\Adminhtml; use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray; use Magento\Framework\DataObject; use Vendor\Module\Block\Adminhtml\Form\Field\CustomColumn; class DynamicField extends AbstractFieldArray { private $dropdownRenderer; protected function _prepareToRender() { $this->addColumn( 'attribute_name', [ 'label' => __('Customer Group'), 'renderer' => $this->getDropdownRenderer(), ] ); $this->addColumn( 'dropdown_field', [ 'label' => __('Purchaseover'), 'class' => 'required-entry', ] ); $this->_addAfter = false; $this->_addButtonLabel = __('Add'); } protected function _prepareArrayRow(DataObject $row) { $options = []; $dropdownField = $row->getDropdownField(); if ($dropdownField !== null) { $options['option_' . $this->getDropdownRenderer()->calcOptionHash($dropdownField)] = 'selected="selected"'; } $row->setData('attributes', $options); } private function getDropdownRenderer() { if (!$this->dropdownRenderer) { $this->dropdownRenderer = $this->getLayout()->createBlock( CustomColumn::class, '', ['data' => ['is_render_to_js_template' => true]]); } return $this->dropdownRenderer; } } |
Create CustomColumn.php file at app\code\Vendor\Module\Block\Adminhtml\Form\Field directory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <?php namespace Vendor\Module\Block\Adminhtml\Form\Field; use Magento\Framework\View\Element\Html\Select; use Magento\Customer\Model\ResourceModel\Group\Collection; use Magento\Backend\Block\Template\Context; use Magento\Customer\Model\Customer\Attribute\Source\GroupSourceLoggedInOnlyInterface; use Magento\Framework\App\ObjectManager; class CustomColumn extends Select { protected $groupdata; public function __construct(Context $context, GroupSourceLoggedInOnlyInterface $groupdata = null, array $data = []) { $this->groupdata = $groupdata ?: ObjectManager::getInstance()->get(GroupSourceLoggedInOnlyInterface::class); parent::__construct($context, $data); } 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() { $customerGroups = $this->groupdata->toOptionArray(); return $customerGroups; } } |
These are the six steps you need to implement to add a dynamic field in Magento 2 admin using system.xml.
If you have questions regarding this blog, feel free to ask in the Comment section below.
I would be happy to answer your query.
Help someone by sharing this post to Magento Community via social media.
Thank you.
Get Weekly Updates
Never miss Magento tips, tricks, tutorials, and news.
Thank you for subscribing.
Something went wrong.