How to add multiselect and dropdown options to Dynamic rows system configuration?

How to add multiselect and dropdown options to Dynamic rows system configuration?

To add dynamic rows with multiselect field into your system configuration settings. First you need to create a module with name M2Expert_DynamicRows or follow the below codes with existing module. This examples shows how to add multiselect country options and Dropdown. See the screenshot below:

To achieve this create the system.xml file into below location

app/code/M2Expert/DynamicRows/etc/adminhtml/system.xml

Code of system.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="general" type="text">
<group id="quantity_ranges" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Quantity Ranges</label>
<field id="ranges" translate="label" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Ranges</label>
<frontend_model>M2Expert\DynamicRows\Block\Adminhtml\Form\Field\Ranges</frontend_model>
<backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
</field>
</group>
</section>
</system>
</config>

Next step is to create the class Ranges into below location:

app/code/M2Expert/DynamicRows/Block/Adminhtml/Form/Field/Ranges.php

Code of Ranges.php

<?php
namespace M2Expert\DynamicRows\Block\Adminhtml\Form\Field;
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\LocalizedException;
use M2Expert\DynamicRows\Block\Adminhtml\Form\Field\TaxColumn;
use M2Expert\DynamicRows\Block\Adminhtml\Form\Field\CountryColumn;
/**
* Class Ranges
*/
class Ranges extends AbstractFieldArray
{
/**
* @var TaxColumn
*/
private $taxRenderer;
/**
* @var CountryColumn
*/
private $countryRenderer;
/**
* Prepare rendering the new field by adding all the needed columns
*/
protected function _prepareToRender()
{
$this->addColumn('from_qty', ['label' => __('From'), 'class' => 'required-entry']);
$this->addColumn('to_qty', ['label' => __('To'), 'class' => 'required-entry']);
$this->addColumn('price', ['label' => __('Price'), 'class' => 'required-entry']);
$this->addColumn('tax', [
'label' => __('Tax'),
'renderer' => $this->getTaxRenderer()
]);
/* Multiselect code */
$this->addColumn('country', [
'label' => __('Country'),
'renderer' => $this->getCountryRenderer(),
'extra_params' => 'multiple="multiple"'
]);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add');
}
/**
* Prepare existing row data object
*
* @param DataObject $row
* @throws LocalizedException
*/
protected function _prepareArrayRow(DataObject $row): void
{
$options = [];
$tax = $row->getTax();
if ($tax !== null) {
$options['option_' . $this->getTaxRenderer()->calcOptionHash($tax)] = 'selected="selected"';
}
$countries = $row->getCountry();
if(count($countries) > 0){
foreach ($countries as $country) {
$options['option_' . $this->getCountryRenderer()->calcOptionHash($country)]
= 'selected="selected"';
}
}
$row->setData('option_extra_attrs', $options);
}
/**
* @return TaxColumn
* @throws LocalizedException
*/
private function getTaxRenderer()
{
if (!$this->taxRenderer) {
$this->taxRenderer = $this->getLayout()->createBlock(
TaxColumn::class,
'',
['data' => ['is_render_to_js_template' => true]]
);
}
return $this->taxRenderer;
}
/* Multiselect renderer for countries */
private function getCountryRenderer()
{
if (!$this->countryRenderer) {
$this->countryRenderer = $this->getLayout()->createBlock(
CountryColumn::class,
'',
['data' => ['is_render_to_js_template' => true]]
);
}
return $this->countryRenderer;
}
}

I have used two classes one is TaxColumn.php which is for dropdown and another one is CountryColumn.php which is for multiselect options.

Location of TaxColumn.php will be

app/code/M2Expert/DynamicRows/Block/Adminhtml/Form/Field/TaxColumn.php

Code of TaxColumn.php

<?php
declare(strict_types=1);
namespace M2Expert\DynamicRows\Block\Adminhtml\Form\Field;
use Magento\Framework\View\Element\Html\Select;
class TaxColumn extends Select
{
/**
* Set "name" for <select> element
*
* @param string $value
* @return $this
*/
public function setInputName($value)
{
return $this->setName($value);
}
/**
* Set "id" for <select> element
*
* @param $value
* @return $this
*/
public function setInputId($value)
{
return $this->setId($value);
}
/**
* Render block HTML
*
* @return string
*/
public function _toHtml(): string
{
if (!$this->getOptions()) {
$this->setOptions($this->getSourceOptions());
}
return parent::_toHtml();
}
private function getSourceOptions(): array
{
return [
['label' => 'Yes', 'value' => '1'],
['label' => 'No', 'value' => '0'],
];
}
}

Location of CountryColumn.php will be

app/code/M2Expert/DynamicRows/Block/Adminhtml/Form/Field/CountryColumn.php

Codes of CountryColumn.php

<?php
declare(strict_types=1);
namespace M2Expert\DynamicRows\Block\Adminhtml\Form\Field;
use Magento\Braintree\Helper\Country;
use Magento\Framework\View\Element\Context;
use Magento\Framework\View\Element\Html\Select;
class CountryColumn extends Select
{
private $countryHelper;
public function __construct(
Context $context,
Country $countryHelper,
array $data = []
) {
parent::__construct($context, $data);
$this->countryHelper = $countryHelper;
}
public function setInputName($value)
{
return $this->setName($value . '[]');
}
public function _toHtml(): string
{
if (!$this->getOptions()) {
$this->setOptions($this->countryHelper->getCountries());
}
$this->setExtraParams('multiple="multiple"');
return parent::_toHtml();
}
}

Thats it! Run the required commands and Cheers!

Back to top