How to Create UI Component Grid In Magento 2

In this article, We're going to explain you How to Create UI Component Grid In Magento 2. If you are like most of the developers, you will have juggled through different websites to find a proper solution to Create UI Component Grid In Magento 2 then you are in a right place.

In our previous articles we've already created the below things. If you are missed it then we'll suggest you to review.

I hope you have understood and applied those steps easily.

Let's get started!!

Step 1: Create di.xml file at app/code/Devhooks/HelloWorld/etc/ and paste the below code.

saveCopyzoom_out_map
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="ui_listing_data_source" xsi:type="string">Devhooks\HelloWorld\Model\ResourceModel\HelloWorld\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
    <virtualType name="Devhooks\HelloWorld\Model\ResourceModel\HelloWorld\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">devhooks_helloworld</argument>
            <argument name="resourceModel" xsi:type="string">Devhooks\HelloWorld\Model\ResourceModel\HelloWorld</argument>
        </arguments>
    </virtualType>
</config>

In above code, we've used devhooks_helloworld as a mainTable name. You have to change it as per your table name.

In our previous article we've already created Model, Resource Model, and Collection files. So, now we need to create a collection file for Grid.

Step 2: Create Collection.php file at app/code/Devhooks/HelloWorld/Model/ResourceModel/HelloWorld/Grid/ and paste the below code.

saveCopyzoom_out_map
<?php

namespace Devhooks\HelloWorld\Model\ResourceModel\HelloWorld\Grid;

use Devhooks\HelloWorld\Model\ResourceModel\HelloWorld\Collection as HelloWorldCollection;
use Magento\Framework\View\Element\UiComponent\DataProvider\Document as HelloWorldModel;

class Collection extends HelloWorldCollection implements \Magento\Framework\Api\Search\SearchResultInterface
{
    protected $aggregations;

    // @codingStandardsIgnoreStart
    public function __construct(
        \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        $mainTable,
        $eventPrefix,
        $eventObject,
        $resourceModel,
        $model = HelloWorldModel::class,
        $connection = null,
        \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
    ) {
        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
        $this->_eventPrefix = $eventPrefix;
        $this->_eventObject = $eventObject;
        $this->_init($model, $resourceModel);
        $this->setMainTable($mainTable);
    }
    // @codingStandardsIgnoreEnd

    public function getAggregations()
    {
        return $this->aggregations;
    }
    public function setAggregations($aggregations)
    {
        $this->aggregations = $aggregations;
    }
    public function getAllIds($limit = null, $offset = null)
    {
        return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams);
    }
    public function getSearchCriteria()
    {
        return null;
    }
    public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null)
    {
        return $this;
    }
    public function getTotalCount()
    {
        return $this->getSize();
    }
    public function setTotalCount($totalCount)
    {
        return $this;
    }
    public function setItems(array $items = null)
    {
        return $this;
    }
}

Now let's create the layout file.

Step 3: Create helloworld_index_index.xml file at app/code/Devhooks/HelloWorld/view/adminhtml/layout/ and paste the below code.

saveCopyzoom_out_map
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <update handle="styles"/>
    <body>
        <referenceContainer name="content">
        	<uiComponent name="ui_listing"/>
        </referenceContainer>
    </body>
</page>

In above code you see we've define uiComponent name with ui_listing. So, now our next process is to create ui_listing.xml which is responsible for uiComponent Grid all settings. But, before that we need to create index.php controller file for render this layout.

Step 4: Create Index.php file at app/code/Devhooks/HelloWorld/Controller/Adminhtml/Index/ and paste the below code.

saveCopyzoom_out_map
<?php

namespace Devhooks\HelloWorld\Controller\Adminhtml\Index;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\View\Result\PageFactory;

class Index extends Action
{
    protected $resultPageFactory;

    public function __construct(
        Context $context,
        PageFactory $resultPageFactory
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
    }
    public function execute()
    {
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
        $resultPage = $this->resultPageFactory->create();
        $resultPage->getConfig()->getTitle()->set(__('Manage Grid'));
        return $resultPage;
    }
}

We've set Manage Grid as a grid title in above code. You can change it as you want.

Step 5: Create ui_listing.xml file at app/code/Devhooks/HelloWorld/view/adminhtml/ui_component/ and paste the below code.

saveCopyzoom_out_map
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">ui_listing.ui_listing_data_source</item>
            <item name="deps" xsi:type="string">ui_listing.ui_listing_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">columns</item>
        <item name="buttons" xsi:type="array">
            <item name="add" xsi:type="array">
                <item name="name" xsi:type="string">add</item>
                <item name="label" xsi:type="string" translate="true">Add New Record</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/form</item>
            </item>
        </item>
    </argument>
    <dataSource name="ui_listing_data_source">
        <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">ui_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
            <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">id</item>
                    </item>
                </item>
            </argument>
        </argument>
    </dataSource>
    <listing>
        <listingToolbar>
            <bookmark name="bookmarks" />
            <columnsControls name="columns_controls" />
            <filters>
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="applied" xsi:type="array">
                            <item name="is_approved" xsi:type="string">1</item>
                        </item>
                    </item>
                </argument>
            </filters>
            <!-- <massaction name="listing_massaction" component="Magento_Ui/js/grid/tree-massactions" class="\Magento\Catalog\Ui\Component\Product\MassAction">
                <action name="delete">
                    <settings>
                        <confirm>
                            <message translate="true">Delete selected items?</message>
                            <title translate="true">Delete items</title>
                        </confirm>
                        <url path="*/*/massDelete" />
                        <type>delete</type>
                        <label translate="true">Delete</label>
                    </settings>
                </action>
            </massaction> -->
            <paging name="listing_paging" />
        </listingToolbar>
    </listing>
    <columns name="columns">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="resizeConfig" xsi:type="array">
                    <item name="enabled" xsi:type="boolean">false</item>
                </item>
            </item>
        </argument>
        <settings>
            <childDefaults>
                <param name="fieldAction" xsi:type="array">
                <item name="provider" xsi:type="string">ui_listing.ui_listing.columns.actions</item>
                <item name="target" xsi:type="string">applyAction</item>
                <item name="params" xsi:type="array">
                    <item name="0" xsi:type="string">edit</item>
                    <item name="1" xsi:type="string">${ $.$data.rowIndex }</item>
                </item>
                </param>
            </childDefaults>
        </settings>
        <selectionsColumn name="ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">55</item>
                    <item name="indexField" xsi:type="string">id</item>
                </item>
            </argument>
        </selectionsColumn>
        <column name="id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">55</item>
                    <item name="filter" xsi:type="string">textRange</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                </item>
            </argument>
        </column>
        <column name="custom_field_1">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Custom Field 1</item>
                </item>
            </argument>
        </column>
        <column name="custom_field_2">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Custom Field 2</item>
                </item>
            </argument>
        </column>
        <column name="status">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Magento\Config\Model\Config\Source\Enabledisable</item>
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="label" translate="true" xsi:type="string">Status</item>
                </item>
            </argument>
        </column>
        <actionsColumn name="actions" class="Devhooks\HelloWorld\Ui\Component\Column\Actions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="indexField" xsi:type="string">id</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>

In above code, we've added filters, button, few fields, and edit/delete action. You can add as much as fields you want.

We've added Add New Record button in this code with */*/form action. But as of now we are not going to create that action because we'll see later in our next article which is How to Create UI Component Form and CRUD Operation In Magento 2.

Also, you can see I have commented massaction action related code above. Because, I want to show you How to Add Mass Action in UI Component Grid in Magento 2 in a seprate article.

As you see in above code we've call Devhooks\HelloWorld\Ui\Component\Column\Actions class. So, our next step is to create Actions.php file and defined location.

Step 6: Create Actions.php file at app/code/Devhooks/HelloWorld/Ui/Component/Column/ and paste the below code.

saveCopyzoom_out_map
<?php

namespace Devhooks\HelloWorld\Ui\Component\Column;

use Magento\Framework\UrlInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Ui\Component\Listing\Columns\Column;

class Actions extends Column
{

    const URL_PATH_EDIT = 'helloworld/index/form';
    const URL_PATH_DELETE = 'helloworld/index/delete';

    protected $urlBuilder;

    public function __construct(
        ContextInterface $context,
        UiComponentFactory $HelloWorldFactory,
        UrlInterface $urlBuilder,
        array $components = [],
        array $data = []
    ) {
        $this->urlBuilder = $urlBuilder;
        parent::__construct($context, $HelloWorldFactory, $components, $data);
    }

    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as &$item) {
                if (isset($item['id'])) {
                    $item[$this->getData('name')] = [
                        'edit' => [
                            'href' => $this->urlBuilder->getUrl(
                                static::URL_PATH_EDIT,
                                [
                                    'id' => $item['id'],
                                ]
                            ),
                            'label' => __('Edit'),
                        ],
                        'delete' => [
                            'href' => $this->urlBuilder->getUrl(
                                static::URL_PATH_DELETE,
                                [
                                    'id' => $item['id'],
                                ]
                            ),
                            'label' => __('Delete'),
                            'confirm' => [
                                'title' => __('Delete Record ?'),
                                'message' => __('Are you sure you wan\'t to delete a record?'),
                            ],
                        ],
                    ];
                }
            }
        }

        return $dataSource;
    }
}

As we defined edit and delete actions in above code. Now we'll create only delete controllers. As I already told you we just create only grid related actions file for now, Later on we'll see for all form related things on our another article.

Step 7: Create Delete.php file at app/code/Devhooks/HelloWorld/Controller/Adminhtml/Index/ and paste the below code.

saveCopyzoom_out_map
<?php

namespace Devhooks\HelloWorld\Controller\Adminhtml\Index;

use Devhooks\HelloWorld\Model\HelloWorldFactory;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;

class Delete extends Action
{
    protected $resultPageFactory;
    protected $HelloWorldFactory;

    public function __construct(
        Context $context,
        PageFactory $resultPageFactory,
        HelloWorldFactory $HelloWorldFactory
    ) {
        $this->resultPageFactory = $resultPageFactory;
        $this->HelloWorldFactory = $HelloWorldFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        $resultRedirectFactory = $this->resultRedirectFactory->create();
        try {
            $id = $this->getRequest()->getParam('id');
            if ($id) {
                $model = $this->HelloWorldFactory->create()->load($id);
                if ($model->getId()) {
                    $model->delete();
                    $this->messageManager->addSuccessMessage(__("Record Delete Successfully."));
                } else {
                    $this->messageManager->addErrorMessage(__("Something went wrong, Please try again."));
                }
            } else {
                $this->messageManager->addErrorMessage(__("Something went wrong, Please try again."));
            }
        } catch (\Exception $e) {
            $this->messageManager->addErrorMessage($e, __("We can't delete record, Please try again."));
        }
        return $resultRedirectFactory->setPath('*/*/index');
    }
}

Step 8: Now, open Command line in folder root of magento and run both commands

saveCopyzoom_out_map
php bin/magento setup:upgrade

php bin/magento cache:flush

Log in to the admin of your Magento 2 and navigate to the grid you'll see grid like the below screenshot.

How to Create UI Component Grid In Magento 2

We have successfully created UI Component Grid, we hope this article helped you to know How to Create UI Component Grid In Magento 2.

Stay Tuned...

Now, let's move to the next step to Create UI Component Form and Perform CRUD Operation In Magento 2. Before that if you want to know How to Add Mass Action in UI Component Grid in Magento 2 then review this article.

Bookmark it for your future reference. Do comment below if you have any other questions or doubts.

P.S. Do share this post with your team.

Special thanks to Rutvik Monpara, He helped me a lot to write a series of How to Create UI Component Grid and Form in Magento 2

Review other articles maybe it'll help you too.




Search
Recent Articles
Tags
Newsletter
Copyright © 2022 devhooks.in All rights reserved.
Ads OFF toggle_off
wifi_off