How to add a custom columns to the Magento 2 products grid

Related Inchoo Services

It’s easy to add a column to the products grid if a value that you want to display in the column is a product attribute. They are already present in the products grid toolbar under Columns control. You just check/uncheck columns that you want to be displayed or removed from the grid. But what if you want to display values like quantity and website that aren’t product attribute? If you continue to read you will learn how to add values like this to the products grid.

Introduction

Because stock management can be turned on/off per product, we will add a new column to the products grid that will display if stock management is turned on or off.
For all of the code examples, I created a Magento 2 module, named Inchoo_Custom.

If you want to learn how to create a Magneto 2 module, you can check this: How to create a basic module in Magento 2

It’s important that Magento’s Magento_Catalog module is loaded before our module, that’s why we will add it under sequence tag in the module.xml file.

app/code/Inchoo/Custom/etc/module.xml

<?xml version="1.0" encoding="utf-8" ?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"
    <module name="Inchoo_Custom" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

After editing module.xml we need to update app/etc/config.php file with console command:

php bin/magento setup:upgrade

Product listing UI component instance

To render products grid Magneto 2 uses Listing UI component instance named product_listing and XML configuration file for it is Magento_Catalog/view/adminhtml/ui_component/product_listing.xml. If we want to customize it we need to create a file in our module with the same path and name.

app/code/Inchoo/Custom/view/adminhtml/ui_component/product_listing.xml

<?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">
    <columns name="product_columns">
        <column name="manage_stock" component="Magento_Ui/js/grid/columns/select" sortOrder="76">
            <settings>
                <addField>true</addField>
                <options class="Magento\Config\Model\Config\Source\Yesno"/>
                <filter>select</filter>
                <dataType>select</dataType>
                <sortable>false</sortable>
                <label translate="true">Manage Stock</label>
            </settings>
        </column>
    </columns>
</listing>

To add new column we need to reference columns UI component named product_columns from the original config file and add our new column to it. We named our column manage_stock with label Manage Stock.

Run this console command to clean cache:

php bin/magneto cache:clean config

After we clean cache we should see our new column in the products grid but data is missing. This is because we didn’t add stock management data to products collection.

Product listing data provider

Best location to add stock management data to products collection is in data provider class used by product_listing UI component instance.

Magento_Catalog/view/adminhtml/ui_component/product_listing.xml

<dataSource name="product_listing_data_source" component="Magento_Ui/js/grid/provider">
    <settings>
        <storageConfig>
            <param name="dataScope" xsi:type="string">filters.store_id</param>
        </storageConfig>
        <updateUrl path="mui/index/render"/>
    </settings>
    <aclResource>Magento_Catalog::products</aclResource>
    <dataProvider class="Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider" name="product_listing_data_source">
        <settings>
            <requestFieldName>id</requestFieldName>
            <primaryFieldName>entity_id</primaryFieldName>
        </settings>
    </dataProvider>
</dataSource>

If we look at the dataSource UI component we will see that the dataProvider class is Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider.

If we look at this data provider class, we will see two properties addFieldStrategies and addFilterStrategies. Both of them are arrays with additional strategies we can do on a collection for a specific column (field). They are respectively called in data provider’s addField and addFilter methods. We will create own strategies for our stock management column.

Manage stock field strategy

First, we will create a field strategy that will add stock management status to the products collection.

Inchoo\Custom\Ui\DataProvider\Product\AddManageStockFieldToCollection

<?php
namespace Inchoo\Custom\Ui\DataProvider\Product;
 
class AddManageStockFieldToCollection implements \Magento\Ui\DataProvider\AddFieldToCollectionInterface
{
    public function addField(\Magento\Framework\Data\Collection $collection, $field, $alias = null)
    {
        $collection->joinField(
            'manage_stock',
            'cataloginventory_stock_item',
            'manage_stock',
            'product_id=entity_id',
            null,
            'left'
        );
    }
}

In AddManageStockFieldToCollection field strategy we implemented addField method from Magento\Ui\DataProvider\AddFieldToCollectionInterface interface. Stock management status comes from the manage_stock column in cataloginventory_stock_item DB table. We used this information and Magento\Eav\Model\Entity\Collection\AbstractCollection::joinField method to add Stock management status to product collection.

Manage stock filter strategy

For times when someone wants to filter grid data by stock management status, we need to create this filtering strategy.

Inchoo\Custom\Ui\DataProvider\Product\AddManageStockFilterToCollection

<?php
namespace Inchoo\Custom\Ui\DataProvider\Product;
 
class AddManageStockFilterToCollection implements \Magento\Ui\DataProvider\AddFilterToCollectionInterface
{
    public function addFilter(\Magento\Framework\Data\Collection $collection, $field, $condition = null)
    {
        if (isset($condition['eq'])) {
            $collection->addFieldToFilter($field, $condition);
        }
    }
}

In AddManageStockFilterToCollection filter strategy we implemented addFilter method from Magento\Ui\DataProvider\AddFilterToCollectionInterface. If grid is filterd by stock management status we will forward filter condtition to Magento\Eav\Model\Entity\Collection\AbstractCollection::addFieldToFilter method.

Add strategies to the product listing data provider

If we want to use just created strategies we need to add them to the product_listing data provider. We will do that in the di.xml file.

app/code/Inchoo/Custom/etc/adminhtml/di.xml

<?xml version="1.0" encoding="utf-8" ?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider">
        <arguments>
            <argument name="addFieldStrategies" xsi:type="array">
                <item name="manage_stock" xsi:type="object">Inchoo\Custom\Ui\DataProvider\Product\AddManageStockFieldToCollection</item>
            </argument>
            <argument name="addFilterStrategies" xsi:type="array">
                <item name="manage_stock" xsi:type="object">Inchoo\Custom\Ui\DataProvider\Product\AddManageStockFilterToCollection</item>
            </argument>
        </arguments>
    </type>
</config>

Run this console command to clean cache:

php bin/magneto cache:clean config

After we clean cache we should see our new column in the products grid with data in it.

You made it all the way down here so you must have enjoyed this post! You may also like:

Development environment for Magento 2 using Docker Tomas Novoselic
, | 0

Development environment for Magento 2 using Docker

Magento 2: How to display static block content in modal overlay Tomas Novoselic
, | 1

Magento 2: How to display static block content in modal overlay

Show product thumbnail in grids Petar Sambolek
Petar Sambolek, | 13

Show product thumbnail in grids

1 comment

  1. Hi
    I am trying to add custom input box with
    $this->addColumn(
    'product_custom_name[]',
    [
    'filter' => false,
    'sortable' => false,
    'header' => __('Custom Name'),
    'renderer' => \Test\Series\Block\Adminhtml\Product\Grid\Renderer\CustomName::class,
    'name' => 'product_custom_name[]',
    'inline_css' => 'product_custom_name',
    'type' => 'input',
    'index' => 'name'
    ]
    );
    with above.
    How can we pass productis in array because when m posting this its very diffuclt to get which custom name is for which product

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.