How to add Multi-select Filter in Backend Admin Grid of Magento 2

How to add Multi select Filter in Backend Admin Grid of Magento 2

Having an online store contains numerous data like customer information, order details, and so on. Having a large number of data makes it difficult for you if you don’t have a proper data filter system. If you have picked the wrong CMS, it will become challenging to handle a large number of data. Compared to other CMS’s, Magento allows you to process a large number of data using powerful grid system & advance filters. Default, Magento 2 comes with a powerful filtration system that helps you to find the information that you are looking for quickly! But many times, it happens that you required some advanced filtered data that you can’t filter using default options.
Considering user convenience, Magento 2 allows you to create your customized filter depending on your business requirements. So, here we are back with another blog tutorial that will help you to add Multi-select filter on the backend admin grid. Here we have used multi-select for filtering products that fall under specific categories.
Firstly, We need to create “product_listing.xml” file inside your “Ui Component” folder at this path.
app\code\Vendor\Extension\view\adminhtml\ui_component\

<pre class="lang:default decode:true">
<?xml version="1.0" encoding="utf-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <listingToolbar name="listing_top">
        <filters name="listing_filters">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
      	          <item name="templates" xsi:type="array">
                        <item name="filters" xsi:type="array">
                        	<item name="select" xsi:type="array">
                            	<item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
                            	<item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
                        	</item>
                        </item>
                    </item>
 	           </item>
            </argument>
        </filters>
    </listingToolbar>
	<columns name="product_columns" class="Magento\Catalog\Ui\Component\Listing\Columns">
        <column name="category_id" class="Vendor\Extension\Ui\Component\Listing\Column\Categorylist">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Vendor\Extension\Model\Categorylist</item>
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="add_field" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Categories</item>
                    <item name="sortOrder" xsi:type="number">100</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>
</pre>

Now, we need to create one more file “Categorylist.php” at following path using below code.
app\code\Vendor\Extension\Ui\Component\Listing\Column\folder\

<pre class="lang:default decode:true">
<?php
namespace Vendor\Extension\Ui\Component\Listing\Column;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
 
class Categorylist extends \Magento\Ui\Component\Listing\Columns\Column
{
 
	protected $_productloader;
	protected $_categoryloader;
 
	public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        \Magento\Catalog\Model\ProductFactory $_productloader,
        \Magento\Catalog\Model\Category $_categoryloader,
    	array $components = [],
    	array $data = []
	) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
        $this->_productloader = $_productloader;
        $this->_categoryloader = $_categoryloader;
	}
	public function prepareDataSource(array $dataSource)
	{
        $fieldName = $this->getData('name');
    	if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {
                $p_id=$item['entity_id'];
     	       $product=$this->_productloader->create()->load($p_id);
                $cats = $product->getCategoryIds();
                $categories=array();
                if(count($cats) ){
                    foreach($cats as $cat){
                        $category = $this->_categoryloader->load($cat);
                        $categories[]=$category->getName();
                    }
                }
                $item[$fieldName]=implode(',',$categories);
        	}
    	}
    	return $dataSource;
	}
}
</pre>

After that we need to create one more file “Categorylist.php” with same name inside our extension model folder.
app\code\Vendor\Extension\Model\

<pre class="lang:default decode:true">
<?php
namespace Vendor\Extension\Model;
class Categorylist implements \Magento\Framework\Option\ArrayInterface
{
	public function __construct(
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collectionFactory
	) {
        $this->_categoryCollectionFactory = $collectionFactory;
 
	}
	public function toOptionArray()
	{
 
        $collection = $this->_categoryCollectionFactory->create();
        $collection->addAttributeToSelect('name');
    	$options = [];
    	foreach ($collection as $category) {
            $options[] = ['label' => $category->getName(), 'value' => $category->getId()];
    	}
    	return $options;
	}
}
</pre>

After that, we need to create “di.xml” file inside our extension etc folder that contains below code.
app\code\Vendor\Extension\etc

<pre class="lang:default decode:true">
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider" type="Vendor\Extension\Ui\ProductDataProvider" />
</config>
</pre>

In this last step, we need to create “ProductDataProvider.php” file inside extension Ui folder and add below code.
app\code\Vendor\Extension\Ui

<pre class="lang:default decode:true">
<?php
namespace Vendor\Extension\Ui;
 
class ProductDataProvider extends \Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider
{
	public function addFilter(\Magento\Framework\Api\Filter $filter)
	{
        if($filter->getField()=='category_id'){
            $this->getCollection()->addCategoriesFilter(array('in' => $filter->getValue()));
    	}
    	elseif (isset($this->addFilterStrategies[$filter->getField()]))
            	{
            $this->addFilterStrategies[$filter->getField()]
                ->addFilter(
                    $this->getCollection(),
                    $filter->getField(),
                    [$filter->getConditionType() => $filter->getValue()]
                );
    	}
            	else
    	{
            parent::addFilter($filter);
    	}
	}
}
</pre>

Tadaa! You have successfully added your custom admin grid filter in Magento 2 backend.

You are free to customize this code according to your need of adding multi-select filter.

Lastly, if you found this blog helpful, don’t forget to share it with your colleagues and Magento Friends and Let us know if you are facing an issue while implementing this code.

Happy Filtering!

Previous Article

How to optimize your Magento UX to provide better customer experience

Next Article

How to Integrate Amazon S3 Cloud Store with Your Magento Store

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Get Connect With Us

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨