Introduction
The most given task for all Magento programmers should be adding more columns with custom data to the Magento base grid. In this blog, we are going to learn how to add columns to the product grid in Magento 2.
Prerequisites
- Create a table
- Join custom table with our wishlist one
- Add column using UI component
I.Create a column to product grid by joining custom table
1. Create a table
- In order to show whichever data we want, we’ll store it in our own table. Here, we’ll simply call it magenest_custom_column with only two columns, id and value.
- At Vendor/Module/etc/db_schema.xml, the content should be something like.
Sample code:
<?xml version="1.0"?> <schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="magenest_custom_column" resource="default" engine="innodb" comment="Magenest Custom Column"> <column xsi:type="int" name="id" unsigned="true" nullable="false" identity="true" comment="Increment ID" /> <column xsi:type="varchar" length="100" name="value" nullable="false" comment="Custom Column Value"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id" /> </constraint> </table> </schema>
2. Join custom table
- As we already know, the listing grid displays data from the table, which is why in order to add our column(s) we must join two tables with each other.
- How to do it, you may ask. A simple plugin file will do the trick.
Sample code
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory"> <plugin name="grid_custom_column" type="Magenest\Grids\Plugin\GridJoinCollection" sortOrder="5" /> </type>
- Before getting to know what this plugin does, we’ll take a quick peek at what getReport function does inside CollectionFactory class.
Sample code
/** * Get report collection * * @param string $requestName * @return Collection * @throws \Exception */ public function getReport($requestName) { if (!isset($this->collections[$requestName])) { throw new \Exception(sprintf('Not registered handle %s', $requestName)); } $collection = $this->objectManager->create($this->collections[$requestName]); if (!$collection instanceof Collection) { throw new \Exception(sprintf('%s is not of Collection type.', $requestName)); } return $collection; }
As we can see here, this function takes in a $requestName as a parameter and return collection of given requests. Consequently, we’ll modify this function so that it will join table based on given table requested.
Sample code
public function afterGetReport( CollectionFactory $subject, $collection, $requestName ) { if ($requestName == ''product_listing_data_source) { $select = $collection->getSelect(); $select->joinLeft( ["secondTable" => $collection->getTable("magenest_custom_column")], 'main_table.increment_id = secondTable.id', array('value') ); } return $collection; }
3. Add column using UI component
- After all the hard work, the last thing we need to do now is to add our column to the grid. Based on whichever grid you want, you can add your custom column just by creating a UI component file with the exact same name as UI grid file. Particularly, to execute this, we only need to place these UI component files inside our module view/adminhtml/ui_component folder.
- Order grid will be written under the file product_listing.xml:
Sample code
<?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="custom_column"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="sortOrder" xsi:type="number">999</item> <item name="filter" xsi:type="string">text</item> <item name="label" translate="true" xsi:type="string">Product Custom Column</item> </item> </argument> </column> </columns> </listing>
4. Result
After that, clear cache and go to the admin site and see the magic for yourself. The result should look something like this.
II. Create a column to product grid by creating a new product attribute
Create new product attribute
Create the file app/code/YourVendor/YourModule/Setup/InstallData.php
Sample code:
<?php namespace YourVendor\YourModule\Setup; use Magento\Framework\Setup\InstallDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; class InstallData implements InstallDataInterface { /** * Eav setup factory * @var EavSetupFactory */ private $eavSetupFactory; /** * Init * @param EavSetupFactory $eavSetupFactory */ public function __construct(\Magento\Eav\Setup\EavSetupFactory $eavSetupFactory) { $this->eavSetupFactory = $eavSetupFactory; } public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) { $eavSetup = $this->eavSetupFactory->create(); $eavSetup->addAttribute( \Magento\Catalog\Model\Product::ENTITY, 'custom_field', [ 'group' => 'General', 'type' => 'varchar', 'label' => 'Custom Field', 'input' => 'text', 'source' => '', 'frontend' => '', 'backend' => '', 'required' => false, 'sort_order' => 50, 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, 'is_used_in_grid' => true, 'is_visible_in_grid' => true, 'is_filterable_in_grid' => true, 'visible' => true, 'is_html_allowed_on_front' => true, 'visible_on_front' => true ] ); } }
- 'is_visible_in_grid' => true will display your attribute in product grid
Execute the InstallData script and verify that it works with run setup:upgrade
You can create a new product attribute in Admin:
- Go to Admin Panel > Stores > Attributes > Product
- Press the Add New Attribute button
- Fill out the Properties, Manage Labels, Storefront Properties section. In tab Advanced Attribute Properties: Filter Yes in the Add to Column Options field in order to add the attribute to the list of column options in the product grid.
2. Result
Conclusions
There are multiple ways to add a custom column to the Magento 2 product grid. In this blog, We’ve shown you simple ways by joining a custom table with your own data or creating a new product attribute. Hope this helps and good luck.
If you have any questions, feel free to leave your comments below.
-
I cannot force mangento to intercept getReport() method. Could you provide some explanation for that?