Magento – Multi select filter in magento2 grid

admingridgrid layoutmagento2

I have a custom module with a grid. Now I need to add a multi-select filter in this grid, I am using XML code not UI code, how can I do this with XML code can anyone help this

Best Answer

I had the same issue and was searching for a solution for this. Requirement adds multi-select in Newsletter Subscribers grid.

Step 1. In the app\code\Company\Module\view\adminhtml\layout\newsletter_subscriber_block.xml

<block class="Magento\Backend\Block\Widget\Grid\Column" as="column" before="column">
    <arguments>
        <argument name="header" xsi:type="string" translate="true">Product Interests</argument>
        <argument name="index" xsi:type="string">product_interests</argument>
        <argument name="header_css_class" xsi:type="string">col-brand</argument>
        <argument name="column_css_class" xsi:type="string">col-brand</argument>
        <argument name="type" xsi:type="string">options</argument>
        <argument name="filter" xsi:type="string">
            Company\Module\Block\Backend\Widget\Grid\Column\Filter\Multiselect
        </argument>
        <argument name="renderer" xsi:type="string">
            Company\Module\Block\Backend\Widget\Grid\Column\Renderer\Multiselect
        </argument>
    </arguments>
</block>

Step 2.

<?php
   namespace Company\Module\Block\Backend\Widget\Grid\Column\Filter;

   class Multiselect extends \Magento\Backend\Block\Widget\Grid\Column\Filter\Select
   {
        protected function _getOptions()
        {
            $emptyOption = ['value' => null, 'label' => ''];

            $optionGroups = $this->getColumn()->getOptionGroups();
            if ($optionGroups) {
                array_unshift($optionGroups, $emptyOption);
                return $optionGroups;
            }

            $colOptions = $this->getColumn()->getOptions();
            if (!empty($colOptions) && is_array($colOptions)) {
                $options = [$emptyOption];

                foreach ($colOptions as $key => $option) {
                    if (is_array($option)) {
                        $options[] = $option;
                    } else {
                        $options[] = ['value' => $key, 'label' => $option];
                    }
                }
                return $options;
            }
            return [];
        }

        /**
         * {@inheritdoc}
         */
        public function getHtml()
        {
            $html = '<select multiple name="' . $this->_getHtmlName() . '" id="' . $this->_getHtmlId() . '"' . $this->getUiId(
                    'filter',
                        $this->_getHtmlName()
                    ) . 'class="no-changes admin__control-select">';
            $value = $this->getValue();
            foreach ($this->_getOptions() as $option) {
                if (is_array($option['value'])) {
                    $html .= '<optgroup label="' . $this->escapeHtml($option['label']) . '">';
                    foreach ($option['value'] as $subOption) {
                        $html .= $this->_renderOption($subOption, $value);
                    }
                    $html .= '</optgroup>';
                } else {
                    $html .= $this->_renderOption($option, $value);
                }
            }
            $html .= '</select>';
            return $html;
        }
    }
    ?>

Step 3.

<?php
namespace Company\Module\Block\Backend\Widget\Grid\Column\Renderer;

use Magento\Framework\DataObject;

class Multiselect extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
{
    /**
     * @param DataObject $row
     *
     * @return string
     */
    public function render(DataObject $row)
    {
        $labels = [];
        $values = explode(',', $this->_getValue($row));
        foreach ($values as $value) {
            $labels[] = $value;
        }

        $renderedValue = implode(', ', $labels);

        if ($this->getColumn()->getEditable()) {
            $result = '<div class="admin__grid-control">';
            $result .= $this->getColumn()->getEditOnly() ? ''
                        : '<span class="admin__grid-control-value">' . $renderedValue . '</span>';

            return $result . $this->_getInputValueElement($row) . '</div>' ;
        }
        return $renderedValue;
    }
}
?>

Step 4. Create column in table newsletter_subscriber value will be comma separate