Magento2 – Grid UI Component

In this blog post we will see how to create a grid component for magento2 admin.

Magento2 introduced a new concept of UIComponents, which enables us to manipulate ui components using xml configuration files. More details can be seen here

To implement grid follow the steps below,

First change controller

<?php

namespace Excellence\Hello\Controller\Adminhtml\World;

class Index extends \Magento\Backend\App\Action
{
   
    protected $resultPageFactory = false;
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
    }
    public function execute()
    {
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu('Excellence_Hello::hello_world_test1');
        $resultPage->addBreadcrumb(__('Hello'), __('Hello'));
        $resultPage->addBreadcrumb(__('World'), __('World'));
        $resultPage->getConfig()->getTitle()->prepend(__('Hello World'));
        return $resultPage;
    }
}

next add this to layout

Excellence\Hello\view\adminhtml\layout\hello_world_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">   
    <update handle="styles"/>   
	<body>
	    <referenceContainer name="content">
	        <uiComponent name="hello_world_grid"/>
	    </referenceContainer>
	</body>
</page>

We have defined ‘uiComponent’ above, which is a new directive. We need to create a uiComponent file with the same name defined in xml.

next add

Excellence\Hello\view\adminhtml\ui_component\hello_world_grid.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">
    <argument name="context" xsi:type="configurableObject">
        <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\Context</argument>
        <argument name="namespace" xsi:type="string">hello_world_grid</argument>
        <!-- this should be same as the file name or uicomponentname -->
    </argument>
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">hello_world_grid.excellence_hello_grid_data_source</item>
             <!-- the format here is uicomponentname.datasourcename -->
            <item name="deps" xsi:type="string">hello_world_grid.excellence_hello_grid_data_source</item>
            <!-- the format here is uicomponentname.datasourcename -->
        </item>
        <item name="spinner" xsi:type="string">hello_world_columns</item>
        <!-- the format here is columns name defined below -->
        <item name="buttons" xsi:type="array">
            <!-- here we can add buttons -->
            <item name="add" xsi:type="array">
                <item name="name" xsi:type="string">add</item>
                <item name="label" xsi:type="string" translate="true">Add New Item</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/new</item>
            </item>
        </item>
    </argument>
    <dataSource name="excellence_hello_grid_data_source">
        <!-- this is data source name, this is used at many places -->
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument>
            <argument name="name" xsi:type="string">excellence_hello_grid_data_source</argument>
            <!-- the same data source name as above -->
            <argument name="primaryFieldName" xsi:type="string">excellence_hello_test_id</argument>
            <!-- our model's primary key -->
            <argument name="requestFieldName" xsi:type="string">id</argument>
            <!-- the field used in ajax url's of grid. just define this as id -->
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
                    <item name="update_url" xsi:type="url" path="mui/index/render"/>
                    <item name="storageConfig" xsi:type="array">
                        <item name="indexField" xsi:type="string">entity_id</item>
                    </item>
                </item>
            </argument>
            <!-- keep above same always -->
        </argument>
    </dataSource>
    <columns name="hello_world_columns">
       <!-- this is columns section name, used above in spinner -->
        <selectionsColumn name="ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="indexField" xsi:type="string">entity_id</item>
                </item>
            </argument>
        </selectionsColumn>
        <!-- this is for the first column which allows to select multiple columns -->
        <!-- below are different column types based on our models -->
        <column name="excellence_hello_test_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                </item>
            </argument>
        </column>
        <column name="title">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">Title</item>
                </item>
            </argument>
        </column>
        <column name="creation_time" class="Magento\Ui\Component\Listing\Columns\Date">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">dateRange</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
                    <item name="dataType" xsi:type="string">date</item>
                    <item name="label" xsi:type="string" translate="true">Purchase Date</item>
                </item>
            </argument>
        </column>
        <column name="update_time"  class="Magento\Ui\Component\Listing\Columns\Date">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">dateRange</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
                    <item name="dataType" xsi:type="string">date</item>
                    <item name="label" xsi:type="string" translate="true">Purchase Date</item>
                </item>
            </argument>
        </column>
        <!--
        <column name="is_active"  class="Magento\Ui\Component\Listing\Columns\Date">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">dateRange</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
                    <item name="dataType" xsi:type="string">date</item>
                    <item name="label" xsi:type="string" translate="true">Purchase Date</item>
                </item>
            </argument>
        </column>
        actions
        -->
    </columns>
</listing>

See the comments in xml to see the meaning of each tags.
Also to get more detailed information on grids, you can see core modules like Magento_Customer, Magento_Sales, Magento_CMS which used these components.

next add in file

Excellence\Hello\etc\di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
 		

	<virtualType name="Excellence\Hello\Model\Resource\Test\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
	    <arguments>
	        <argument name="mainTable" xsi:type="string">excellence_hello_test</argument>
	        <argument name="resourceModel" xsi:type="string">Excellence\Hello\Model\ResourceModel\Test</argument>
	    </arguments>
	</virtualType>

	<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
	    <arguments>
	        <argument name="collections" xsi:type="array">
	            <item name="excellence_hello_grid_data_source" xsi:type="string">Excellence\Hello\Model\Resource\Test\Grid\Collection</item>
	        </argument>
	    </arguments>
	</type>

</config>

this file is important. this will actually connected the dataSource to the model we are using for grid.

On this is done, when click on our menu item we should the admin grid show up.