8

enter image description here

This image what I already have. I have to make second column as multiselect. How to achieve this? This should be configuration field.

4

1 Answer 1

17

Create Field class like below copied from magento dev docs

<?php
namespace Vendor\Module\Block\Adminhtml\Form\Field;

use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\LocalizedException;
use Vendor\Module\Block\Adminhtml\Form\Field\TaxColumn;

/**
 * Class Ranges
 */
class Ranges extends AbstractFieldArray
{
    /**
     * @var TaxColumn
     */
    private $taxRenderer;

    /**
     * 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(
                \Vendor\Module\Block\Adminhtml\Form\Field\CountryColumn::class,
                '',
                ['data' => ['is_render_to_js_template' => true]]
            );
        }
        return $this->countryRenderer;
    }
}

Create CountryColumn class under

app/code/Vendor/Module/Block/Adminhtml/Form/Field/CountryColumn.php

with below content

<?php
declare(strict_types=1);

namespace Vendor\Module\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();
    }
}
3
  • 2
    Man, you are wizard, thank you very much! Dec 26, 2019 at 15:48
  • 2
    good solution. (y) Dec 27, 2019 at 6:01
  • I have implemented this, this is saving data to databse but not able to see it selected on load. Can you suggest me? [option_extra_attrs] => Array ( [option_4200685455] => selected="selected" ) I get this extra in $row array. but not showing as selected.
    – Dolly
    Apr 4 at 19:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.