How To Create UI Component Grid in Magento 2

Hello Everyone,

In this blog, we will learn about how to Create UI Component Grid in Magento 2.

Magento 2 grid is a way to list items in a database table.

Magento 2 gives grids like order grid, product grid etc. but still sometimes we are required to create a new custom admin grid.

Without wasting your time, let us guide you straight away. Follow the easy step given below to Create UI Component Grid in Magento 2.

STEPS FOR CREATE UI COMPONENT GRID IN MAGENTO 2

Step 1: Create di.xml file

In the below code we set the main table name as “magecurious_custom_table”, you can change it as per your table name.

app/code/Vendor/Extension/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">
    <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">Vendor\Extension\Model\ResourceModel\BookInfo
\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
    <virtualType name="Vendor\Extension\Model\ResourceModel\BookInfo\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">magecurious_custom_table</argument>
            <argument name="resourceModel" xsi:type="string">Vendor\Extension\Model\ResourceModel\BookInfo</argument>
        </arguments>
    </virtualType>
</config>

Step 2: Create Collection.php file

We already created Model, Resource Model and Collection of BookInfo in our previous blog so now here we create a collection file for grid.


app/code/Vendor/Extension/Model/ResourceModel/BookInfo/Grid/Collection.php

<?php

namespace Vendor\Extension\Model\ResourceModel\BookInfo\Grid;

use Vendor\Extension\Model\ResourceModel\BookInfo\Collection as BookInfoCollection;
use Magento\Framework\View\Element\UiComponent\DataProvider\Document as BookInfoModel;

class Collection extends BookInfoCollection 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 = BookInfoModel::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;
    }
}

Step 3: Create helloworld_index_index.xml file

This file is used to create a ui component grid.

app/code/Vendor/Extension/view/adminhtml/layout/helloworld_index_index.xml

<?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>

Step 4: Create Index.php file.

In the code below we can set the title “manage grid”, you can change what you want. This controller is used to render the layout of the grid.

app/code/Vendor/Extension/Controller/Adminhtml/Index/Index.php

<?php

namespace Vendor\Extension\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;
    }
}

Step 5: Create ui_listing.xml file

In below code we can add filters, Add new Record Button, database column fields, edit/delete actions.

You can add as many database column fields as you want.

app/code/Vendor/Extension/view/adminhtml/ui_component/ui_listing.xml

<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>
            <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="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">Field 1</item>
                </item>
            </argument>
        </column>
        <column name="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">Field 2</item>
                </item>
            </argument>
        </column>
        <actionsColumn name="actions" class="Vendor\Extension\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>

Step 6: Create Actions.php file

app/code/Vendor/Extension/Ui/Component/Column/Actions.php

<?php

namespace Vendor\Extension\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,
        ComponentFactory $BookInfoFactory,
        UrlInterface $urlBuilder,
        array $components = [],
        array $data = []
    ) {
        $this->urlBuilder = $urlBuilder;
        parent::__construct($context, $BookInfoFactory, $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;
    }
}

Step 7: Create Delete.php file

Here we can only create delete action full form action will be created in our next blog.

app/code/Vendor/Extension/Controller/Adminhtml/Index/Delete.php

<?php

namespace Vendor\Extension\Controller\Adminhtml\Index;

use Vendor\Extension\Model\BookInfoFactory;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;

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

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

    public function execute()
    {
        $resultRedirectFactory = $this->resultRedirectFactory->create();
        try {
            $id = $this->getRequest()->getParam('id');
            if ($id) {
                $model = $this->BookInfoFactory->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: Finally run the below commands

$ php bin/magento setup:upgrade

$ php bin/magento cache:clean

$ php bin/magento cache:flush

Step 8: Output:

Final Thoughts:

So this was the easiest way which we have told you in this blog. This is how you can Create UI Component Grid in Magento 2. Hope you liked the blog.

So quickly go to the comment box and tell me how you like this blog?

Stay tuned with us on our site to get new updates of Magento.

Thanks for reading and visiting our site.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

Leave a Reply

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