Magento 2: Add Categories Column To Product Grid In Admin And Make It Filterable

Magento 2: Add Categories Column To Product Grid In Admin And Make It Filterable

Now we have successfully added “Categories” column to product grid and also this column is filterable. In this article we will add a custom column to the product grid. We will also add a filter for this column. For the sake of this article, we will add a “Categories” column to the product grid. That will show which categories the product belongs to, but you can add any column you want. You just need to populate the column with relevant data.

Creating New Module:

First create a new module. For this tutorial we create a module RLTS_Helloworld. Then create file: app/code/RLTS/Helloworld/view/adminhtml/ui_component/product_listing.xml. Put following code in this file:

<?xml version="1.0"?>
 
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
   <columns name="product_columns" class="Magento\Catalog\Ui\Component\Listing\Columns">
      <column name="category_id" class="RLTS\Helloworld\Ui\Component\Listing\Column\Category">
         <argument name="data" xsi:type="array">
            <item name="options" xsi:type="object">RLTS\Helloworld\Model\Category\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="label" xsi:type="string" translate="true">Categories</item>
               <item name="sortOrder" xsi:type="number">75</item>
               <item name="dataType" xsi:type="string">select</item>
            </item>
         </argument>
      </column>
   </columns>
</listing>

The following line

 <column name="category_id" class="RLTS\Helloworld\Ui\Component\Listing\Columns\Category">

specifies the unique id for column, in this case category_id. It also specifies a Category class that will populate this column.

The following line:

<item name="options" xsi:type="object">RLTS\Helloworld\Model\Category\Categorylist</item>

specifies a CategoryList class which will populate the filter for this column. In magento2, filters are shown separately at top of product grid.

The following line:

<item name="filter" xsi:type="string">select</item>

specifies that in filters, the field will appear as a dropdown (select input).

The following line:

<item name="label" xsi:type="string" translate="true">Categories</item>

determines the label of the field in product grid.

Creating Files:

app/code/RLTS/Helloworld/Ui/Component/Listing/Column/Category.php
This file will have the code that will actually populate the column with data. In our case we are getting categories. You can populate with any data you want. Put in following code in this file.

<?php
 
namespace RLTS\Helloworld\Ui\Component\Listing\Column;
 
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
 
class Category extends \Magento\Ui\Component\Listing\Columns\Column
{
 
   public function prepareDataSource(array $dataSource)
   {
      $fieldName = $this->getData('name');
      if (isset($dataSource['data']['items'])) {
         foreach ($dataSource['data']['items'] as & $item) {
         //print_r($item);die;
         $productId=$item['entity_id'];
         //$product=$this->_productloader->create()->load($p_id);
         //$product = $objectManager->get('Magento\Catalog\Model\Product')->loa‌​d($p_id);
         //$productId = $p_id;
         $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
         $product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);
         $cats = $product->getCategoryIds();
         //$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
         $categories=array();
         if(count($cats) ){
            foreach($cats as $cat){
               $category = $objectManager->create('Magento\Catalog\Model\Category')->load($cat);
                $categories[]=$category->getName();
            }
         }
         $item[$fieldName]=implode(',',$categories);
         }
      }
   return $dataSource;
   }
}

Now create following file:

app/code/RLTS/Helloworld/Model/Category/Categorylist.php

This file will have the code that will fill Categories dropdown in filters.

Put following code in this file:

<?php
 
namespace RLTS\Helloworld\Model\Category;
 
class CategoryList implements \Magento\Framework\Option\ArrayInterface
{
   public function __construct(
   \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collectionFactory
   ) {
      $this->_categoryCollectionFactory = $collectionFactory;
 
   }
   public function toOptionArray($addEmpty = true)
   {
 
      /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */
      $collection = $this->_categoryCollectionFactory->create();
      $collection->addAttributeToSelect('name');//->addRootLevelFilter()->load();
      $options = [];
      if ($addEmpty) {
         $options[] = ['label' => __('-- Please Select a Category --'), 'value' => ''];
      }
      foreach ($collection as $category) {
         $options[] = ['label' => $category->getName(), 'value' => $category->getId()];
      }
      return $options;
   }
}

Finally we need to override a Ui Dataprovider.

Create following file:
app/code/RLTS/Helloworld/etc/di.xml
Put following code

<?xml version="1.0"?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider" type="RLTS\Helloworld\Ui\DataProvider\Product\ProductDataProvider" />
</config>

Also create following file:
app/code/RLTS/Helloworld/Ui/DataProvider/Product/ProductDataProvider.php

Put following code in this file:

<?php
/**
* @copyright Copyright (c) 2016 https://chillydraji.wordpress.com
*/
namespace RLTS\Helloworld\Ui\DataProvider\Product;
 
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);
      }
   }
}

Finally,  we have successfully added “Categories” column to product grid and also this column is filterable.

Back to blog