I want to create dynamic field configuration with dropdown , can anyone help me on this.
2 Answers
Use below snippet:
we need to define the field in etc/adminhtml/system.xml
<group id="additional" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Additional</label>
<field id="customfields" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Dynamic Fields</label>
<frontend_model>Vendor\Module\Block\Adminhtml\Form\Field\DynamicFields</frontend_model>
<backend_model>Vendor\Module\Config\Backend\DynamicFields</backend_model>
</field>
</group>
Vendor/Module/Block/Adminhtml/Form/Field/DynamicFields.php
<?php
namespace Vendor\Module\Block\Adminhtml\Form\Field;
class DynamicFields extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray
{
/**
* @var Inputgroup
*/
protected $_groupRenderer;
/**
* Retrieve group column renderer
*
* @return Inputgroup
*/
protected function _getGroupRenderer()
{
if (!$this->_groupRenderer) {
$this->_groupRenderer = $this->getLayout()->createBlock(
\Vendor\Module\Block\Adminhtml\Form\Field\DropdownValues::class,
'',
['data' => ['is_render_to_js_template' => true]]
);
$this->_groupRenderer->setClass('dropdown_group_select');
}
return $this->_groupRenderer;
}
/**
* Prepare to render
*
* @return void
*/
protected function _prepareToRender()
{
$this->addColumn('fieldlabel', ['label' => __('Label'), 'class' => 'required-entry']);
$this->addColumn(
'dropdown_group_id',
['label' => __('Dropdown'),'size' => '130px',
'renderer' => $this->_getGroupRenderer(), 'class' => 'required-entry']
);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add More Field');
}
/**
* Prepare existing row data object
*
* @param \Magento\Framework\DataObject $row
* @return void
*/
protected function _prepareArrayRow(\Magento\Framework\DataObject $row)
{
$optionExtraAttr = [];
$optionExtraAttr['option_' . $this->_getGroupRenderer()->calcOptionHash($row->getData('dropdown_group_id'))] =
'selected="selected"';
$row->setData(
'option_extra_attrs',
$optionExtraAttr
);
}
}
Vendor/Module/Block/Adminhtml/Form/Field/DropdownValues.php
Assign your values array in $this->_inputGroups
<?php
namespace Vendor\Module\Block\Adminhtml\Form\Field;
use Magento\Framework\Api\SearchCriteriaBuilder;
/**
* HTML select element block with customer groups options
*/
class Inputtype extends \Magento\Framework\View\Element\Html\Select
{
/**
* Customer groups cache
*
* @var array
*/
private $_inputGroups;
/**
* Flag whether to add group all option or no
*
* @var bool
*/
protected $_addGroupAllOption = true;
/**
* @var SearchCriteriaBuilder
*/
protected $searchCriteriaBuilder;
/**
* Construct
*
* @param \Magento\Framework\View\Element\Context $context
* @param GroupManagementInterface $groupManagement
* @param GroupRepositoryInterface $groupRepository
* @param SearchCriteriaBuilder $searchCriteriaBuilder
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Context $context,
SearchCriteriaBuilder $searchCriteriaBuilder,
array $data = []
) {
parent::__construct($context, $data);
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
}
/**
* Retrieve allowed customer groups
*
* @param int $groupId return name by customer group id
* @return array|string
*/
protected function _getInputTypes($groupId = null)
{
if ($this->_inputGroups === null) {
// Add your Dropdown values here
$this->_inputGroups = array('value 1', 'value 2');
}
return $this->_inputGroups;
}
/**
* @param string $value
* @return $this
*/
public function setInputName($value)
{
return $this->setName($value);
}
/**
* Render block HTML
*
* @return string
*/
public function _toHtml()
{
if (!$this->getOptions()) {
foreach ($this->_getInputTypes() as $inputId => $inputLabel) {
$this->addOption($inputId, addslashes($inputLabel));
}
}
return parent::_toHtml();
}
}
Vendor/Module/Config/Backend/DynamicFields.php
<?php
namespace Vendor\Module\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;
/**
* Backend for serialized array data
*/
class DynamicFields extends \Magento\Framework\App\Config\Value
{
/**
* Json Serializer
*
* @var SerializerInterface
*/
protected $serializer;
/**
* ShippingMethods constructor
*
* @param SerializerInterface $serializer
* @param Context $context
* @param Registry $registry
* @param ScopeConfigInterface $config
* @param TypeListInterface $cacheTypeList
* @param AbstractResource|null $resource
* @param AbstractDb|null $resourceCollection
* @param array $data
*/
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);
}
/**
* Prepare data before save
*
* @return void
*/
public function beforeSave()
{
/** @var array $value */
$value = $this->getValue();
unset($value['__empty']);
$encodedValue = $this->serializer->serialize($value);
$this->setValue($encodedValue);
}
/**
* Process data after load
*
* @return void
*/
protected function _afterLoad()
{
/** @var string $value */
$value = $this->getValue();
if($value){
$decodedValue = $this->serializer->unserialize($value);
$this->setValue($decodedValue);
}
}
}
I need a custom dropdown, because I have many options how do we put a search filter into the dropdown?
-
Please check if magento.stackexchange.com/questions/206316/… works for u Commented May 17, 2020 at 5:25