Dynamic fields in system configuration in Magento 2
Hi all,
Today this post is all about the dynamic field in the system config area
Recently someone raised the question that How TO Add a TextArea in Dynamic Rows in System.xml
So today I will add a snippet which will helpful for adding any type of field using the renderer functionality.
TODO
Create system.xml file
Create Frontend model in Block section
Create field renderer file like select box or textbox
Path: app/code/Nilesh/Prefech/etc/adminhtml/system.xml
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> <system> <section id="web"> <group id="resource_hints" translate="label comment" sortOrder="35" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Resource Hints</label> <comment>Comment</comment> <field id="config" translate="label comment" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Configure</label> <comment>Your comment</comment> <frontend_model>Nilesh\Prefech\Block\System\Config\Form\Field\FieldArray</frontend_model> <backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model> </field> </group> </section> </system> </config>
Path: app/code/Nilesh/Prefech/Block/System/Config/Form/Field/FieldArray.php
<?php namespace Nilesh\Prefech\Block\System\Config\Form\Field; use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray; class FieldArray extends AbstractFieldArray { /** @var array $_columns */ protected $_columns = []; /** @var bool $_addAfter */ protected $_addAfter = true; /** @var $_addButtonLabel */ protected $_addButtonLabel; /** @var $resourceTypeRenderer */ private $resourceTypeRenderer; /** @var $preloadTypeRenderer */ private $preloadTypeRenderer; /** @var $textAreaType */ private $textAreaType; /** * FieldArray Constructor */ protected function _construct() { parent::_construct(); $this->_addButtonLabel = __('Add Resource Hint'); } /** * @return \Magento\Framework\View\Element\BlockInterface * @throws \Magento\Framework\Exception\LocalizedException */ private function listResourceHintTypes() { if (!$this->resourceTypeRenderer) { $this->resourceTypeRenderer = $this->getLayout()->createBlock( '\Nilesh\Prefech\Block\Adminhtml\Form\Field\ResourceHintType', '', ['data' => ['is_render_to_js_template' => true]] ); } return $this->resourceTypeRenderer; } /** * @return \Magento\Framework\View\Element\BlockInterface * @throws \Magento\Framework\Exception\LocalizedException */ private function listPreloadTypes() { if (!$this->preloadTypeRenderer) { $this->preloadTypeRenderer = $this->getLayout()->createBlock( '\Nilesh\Prefech\Block\Adminhtml\Form\Field\PreloadType', '', ['data' => ['is_render_to_js_template' => true]] ); } return $this->preloadTypeRenderer; } /** * @return \Magento\Framework\View\Element\BlockInterface * @throws \Magento\Framework\Exception\LocalizedException */ private function textAreaTypes() { if (!$this->textAreaType) { $this->textAreaType = $this->getLayout()->createBlock( '\Nilesh\Prefech\Block\Adminhtml\Form\Field\Textarea', '' ); } return $this->textAreaType; } /** * @throws \Magento\Framework\Exception\LocalizedException */ protected function _prepareToRender() { $this->addColumn( 'type', [ 'label' => __('Type'), 'renderer' => $this->listResourceHintTypes(), ] ); $this->addColumn( 'resource', [ 'label' => __('Resource') ] ); $this->addColumn( 'sort_order', [ 'label' => __('Sort Order'), 'renderer' => $this->textAreaTypes() ] ); $this->addColumn( 'preload_as', [ 'label' => __('Preload as'), 'renderer' => $this->listPreloadTypes() ] ); $this->_addAfter = false; } /** * @param \Magento\Framework\DataObject $row * * @throws \Magento\Framework\Exception\LocalizedException */ protected function _prepareArrayRow(\Magento\Framework\DataObject $row) { $type = $row->getType(); $options = []; if ($type) { $options['option_' . $this->listResourceHintTypes()->calcOptionHash($type)] = 'selected="selected"'; } $preloadAs = $row->getPreloadAs(); if ($preloadAs) { $options['option_' . $this->listPreloadTypes()->calcOptionHash($preloadAs)] = 'selected="selected"'; } $row->setData('option_extra_attrs', $options); } /** * @param string $columnName * * @return string * @throws \Exception */ public function renderCellTemplate($columnName) { if ($columnName == "type") { $this->_columns[$columnName]['class'] = 'input-select required-entry'; } if ($columnName == 'resource') { $this->_columns[$columnName]['class'] = 'input-text required-entry'; $this->_columns[$columnName]['style'] = 'width: 200px'; } if ($columnName == 'sort_order') { $this->_columns[$columnName]['class'] = 'input-text required-entry validate-number'; $this->_columns[$columnName]['style'] = 'width: 50px'; } if ($columnName == "preload_as") { $this->_columns[$columnName]['class'] = 'input-select'; } return parent::renderCellTemplate($columnName); } }
Path: app/code/Nilesh/Prefech/Block/Adminhtml/Form/Field/Textarea.php
<?php namespace Nilesh\Prefech\Block\Adminhtml\Form\Field; // use Magento\Framework\View\Element\Context; class Textarea extends \Magento\Framework\View\Element\Template { /** * @return string */ public function _toHtml() { $inputName = $this->getInputName(); $columnName = $this->getColumnName(); $column = $this->getColumn(); return '<textarea id="' . $this->getInputId().'" name="' . $inputName . '" ' . ($column['size'] ? 'size="' . $column['size'] . '"' : '') . ' class="' . (isset($column['class']) ? $column['class'] : 'input-text') . '"'. (isset($column['style']) ? ' style="'.$column['style'] . '"' : '') . '></textarea>'; } }
Path: app/code/Nilesh/Prefech/Block/Adminhtml/Form/Field/PreloadType.php
<?php namespace Nilesh\Prefech\Block\Adminhtml\Form\Field; use Magento\Framework\View\Element\Context; use Magento\Framework\View\Element\Html\Select; class PreloadType extends Select { /** @var array $_options */ protected $_options = [ 'script' => 'Script', 'style' => 'Style', 'font' => 'Font', 'image' => 'Image', 'fetch' => 'Fetch/XHR', 'document' => 'Document' ]; /** * PreloadType constructor. * * @param Context $context * @param array $data */ public function __construct( Context $context, array $data = [] ) { parent::__construct($context, $data); } /** * @return string */ public function _toHtml() { if (!$this->getOptions()) { foreach ($this->_options as $value => $label) { $this->addOption($value, $label); } } $this->setClass('input-select required-entry'); $this->setExtraParams('style="width: 100px;"'); return parent::_toHtml(); } /** * @param $value * * @return mixed */ public function setInputName($value) { return $this->setName($value); } }
That’s it
This snippet is not complete as my aim was to give an idea
Please refer this link for more – https://daan.dev/magento-2-extensions/resource-hints/
Any question just comment below
Happy Coding
You all are the semicolon to my statements; Please support me; Thanks