Magento Tutorials

How to Create UI Component Grid and Form in Magento 2

Hello, Magento Friends!

Today’s subject matter is How to Create UI Component Grid and Form in Magento 2. The UI component grid and form are the most paramount features for admin users. Despite that, there are numerous developers who encounter challenges while creating UI component grids and forms in Magento 2 backend panel.

Magento 2 Grid is a sort of record that arranges the details in your database report and provides you some peculiarities like sorting, filtering, deleting, updating items, and more. 

For this reason, I will be explaining to you to Create Magento 2 UI Component Grid and Form.

Also, take a peek at – How to Filter UI Component Grid Collection in Magento 2

Steps to Create UI Component Grid and Form in Magento 2

Step 1:  Create database schema

app\code\Vendor\Extension\Setup\InstallSchema.php

<?php
namespace Vendor\Extension\Setup;

class InstallSchema implements \Magento\Framework\Setup\InstallSchemaInterface
{
    public function install(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();
        if (!$installer->tableExists('magecomp_customtable')) {
            $table = $installer->getConnection()->newTable(
                $installer->getTable('magecomp_customtable')
            )
                ->addColumn('id',
                    \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                    null,
                    [
                        'identity' => true,
                        'nullable' => false,
                        'primary' => true,
                        'unsigned' => true,
                    ], 'ID')
                ->addColumn(
                    'name',
                    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    255,
                    ['nullable => false'],
                    'Name'
                )
                ->addColumn('content',
                    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    '64k',
                    [],
                    'Content'
                )
                ->addColumn('title',
                    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    255,
                    [],
                    'Title'
                );

            $installer->getConnection()->createTable($table);
            $installer->getConnection()->addIndex(

                $installer->getTable('magecomp_customtable'),
                $setup->getIdxName($installer->getTable('magecomp_customtable'),
                    ['name', 'content', 'title'],
                    \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
                ),
                    ['name', 'content', 'title'],
                    \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
            );
        }
        $installer->endSetup();
    }
}

Step 2:  create a routes.xml

app\code\Vendor\Extension\etc\adminhtml\

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">

    <router id="admin">

        <route id="uiexample" frontName="uiexample">

            <module name="Vendor_Extension"/>

        </route>

    </router>

</config>

Step 3:  create a menu.xml

app\code\Vendor\Extension\etc\adminhtml\

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Magento/Backend/etc/menu.xsd">

    <menu>

        <add id="Vendor_Extension::view" title="Magecomp" module="Vendor_Extension" sortOrder="50" resource="Vendor_Extension::view"/>

        <add id="Vendor_Extension::menu" title="Manage Grid" module="Vendor_Extension" sortOrder="20" parent="Vendor_Extension::view" action="uiexample/index/index" resource="Vendor_Extension::menu"/>

    </menu>

</config>

Step 4: create a di.xml

app\code\Vendor\Extension\etc\

<?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="Vendor\Extension\Model\ResourceModel\Grid\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">magecomp_customtable</argument>
            <argument name="resourceModel" xsi:type="string">Vendor\Extension\Model\ResourceModel\Custom</argument>
        </arguments>
    </virtualType>

    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="grid_record_grid_list_data_source" xsi:type="string">Vendor\Extension\Model\ResourceModel\Grid\Grid\Collection</item>
            </argument>
        </arguments>
    </type>

</config>

Step 5: create a Custom.php Model File

app\code\Vendor\Extension\Model\

<?php

namespace Vendor\Extension\Model;

use Magento\Framework\Model\AbstractModel;

class Custom extends AbstractModel  {

const CACHE_TAG = 'id';

    protected function _construct()

{

        $this->_init('Vendor\Extension\Model\ResourceModel\Custom');

  }

public function getIdentities()

    {

        return [self::CACHE_TAG . '_' . $this->getId()];

    }

}

Step 6: we will also need to create a Custom.php ResourceModel file

app\code\Vendor\Extension\Model\ResourceModel\

<?php

namespace Vendor\Extension\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class Custom extends AbstractDb

{

    protected function _construct()

    {

        $this->_init('magecomp_customtable', 'id');

    }

}

Step 7: we will create a Collection.php file 

app\code\Vendor\Extension\Model\ResourceModel\Custom\

<?php

namespace Vendor\Extension\Model\ResourceModel\Custom;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection

{

    protected function _construct()

    {

        $this->_init('Vendor\Extension\Model\Custom','Vendor\Extension\Model\ResourceModel\Custom');

    }

}

Step 8: Next step is to create a DataProvider.php file

app\code\Vendor\Extension\Model\

<?php

namespace Vendor\Extension\Model;

use Vendor\Extension\Model\ResourceModel\Custom\CollectionFactory;

class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider

{

    protected $loadedData;

    public function __construct(

        $name,

        $primaryFieldName,

        $requestFieldName,

        CollectionFactory $CollectionFactory,

        array $meta = [],

        array $data = []

    ) {

        $this->collection = $CollectionFactory->create();

        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);

    }

    public function getData()

    {

        if (isset($this->loadedData)) {

            return $this->loadedData;

        }

        $items = $this->collection->getItems();

        foreach ($items as $item) {

            $this->loadedData[$item->getId()] = $item->getData();

        }

        return $this->loadedData;

    }

}

Step 9: After that, we will now create an Index.php file in the Controller

app\code\Vendor\Extension\Controller\Adminhtml\Index\

<?php

namespace Vendor\Extension\Controller\Adminhtml\Index;

class Index extends \Magento\Backend\App\Action

{

    protected $resultPageFactory;

    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->getConfig()->getTitle()->prepend(__('Manage Grid'));

        return $resultPage;

    }

}

Step 10:  we also create an Add.php file

app\code\Vendor\Extension\Controller\Adminhtml\Index\

<?php

namespace Vendor\Extension\Controller\Adminhtml\Index;

use Magento\Framework\Controller\ResultFactory;

class Add extends \Magento\Backend\App\Action

{

    protected $resultPageFactory;

    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(ResultFactory::TYPE_PAGE);

        $resultPage->getConfig()->getTitle()->prepend(__('Add New Record'));

        return $resultPage;

    }

}

Step 11: In the layout folder, we will be adding a UI component grid and form in our demo project.

Let’s create a uiexample_index_index.xml file

app\code\Vendor\Extension\view\adminhtml\layout\

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

    <body>

        <referenceContainer name="content">

            <uiComponent name="custom_grid_listing"/>

        </referenceContainer>

    </body>

</page>

Step 12:  we also need to create an uiexample_index_add.xml file

app\code\Vendor\Extension\view\adminhtml\layout\

<?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="uiexample_form"/>

        </referenceContainer>

    </body>

</page>

Step 13: In the ui_component folder, produce the UI Grid and Form file.

Create  custom_grid_listing.xml file

app\code\Vendor\Extension\view\adminhtml\ui_component\

<?xml version="1.0"?>

<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">custom_grid_listing.grid_record_grid_list_data_source</item>

            <item name="deps" xsi:type="string">custom_grid_listing.grid_record_grid_list_data_source</item>

        </item>

        <item name="spinner" xsi:type="string">grid_records_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">*/*/add</item>

            </item>

        </item>

    </argument>

    <listingToolbar name="listing_top">

        <argument name="data" xsi:type="array">

            <item name="config" xsi:type="array">

                <item name="sticky" xsi:type="boolean">true</item>

            </item>

        </argument>

        <bookmark name="bookmarks"/>

        <columnsControls name="columns_controls"/>

        <filterSearch name="fulltext"/>

        <filters name="listing_filters"/>

        <paging name="listing_paging"/>

        <exportButton name="export_button"/>

    </listingToolbar>

    <dataSource name="grid_record_grid_list_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">grid_record_grid_list_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>

    <columns name="grid_records_columns">

        <selectionsColumn name="ids">

           <argument name="data" xsi:type="array">

               <item name="config" xsi:type="array">

                   <item name="indexField" xsi:type="string">id</item>

                   <item name="sorting" xsi:type="string">desc</item>

                   <item name="sortOrder" xsi:type="number">0</item>

               </item>

           </argument>

       </selectionsColumn>

       

       <column name="id">

           <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">Id</item>

               </item>

           </argument>

       </column>

       <column name="name">

           <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">Name</item>

               </item>

           </argument>

       </column>

       <column name="content" >

           <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">Content</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="label" xsi:type="string" translate="true">Title</item>

               </item>

           </argument>

       </column>

        

    </columns>

</listing>

Step 14:  we will create an uiexample_form.xml UI grid file

app\code\Vendor\Extension\view\adminhtml\ui_component\

<?xml version="1.0" encoding="UTF-8"?>

<form 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">uiexample_form.grid_record_grid_list_data_source</item>

            <item name="deps" xsi:type="string">uiexample_form.grid_record_grid_list_data_source</item>

        </item>

        <item name="label" xsi:type="string" translate="true">Add New Record</item>

        <item name="config" xsi:type="array">

            <item name="dataScope" xsi:type="string">data</item>

            <item name="namespace" xsi:type="string">uiexample_form</item>

        </item>

        <item name="template" xsi:type="string">templates/form/collapsible</item>

        <item name="buttons" xsi:type="array">

            <item name="save" xsi:type="string">Vendor\Extension\Block\Adminhtml\Edit\Save</item>

        </item>

    </argument>

    <dataSource name="grid_record_grid_list_data_source">

        <argument name="dataProvider" xsi:type="configurableObject">

            <argument name="class" xsi:type="string">Vendor\Extension\Model\DataProvider</argument>

            <argument name="name" xsi:type="string">grid_record_grid_list_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="submit_url" xsi:type="url" path="*/*/save"/>

                </item>

            </argument>

        </argument>

        <argument name="data" xsi:type="array">

            <item name="js_config" xsi:type="array">

                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>

            </item>

        </argument>

    </dataSource>

    <fieldset name="general_information">

        <argument name="data" xsi:type="array">

            <item name="config" xsi:type="array">

                <item name="collapsible" xsi:type="boolean">false</item>

                <item name="label" xsi:type="string" translate="true">General Information</item>

                <item name="sortOrder" xsi:type="number">20</item>

            </item>

        </argument>

        <field name="name" sortOrder="10" formElement="input">

            <settings>

                <dataType>text</dataType>

                <visible>true</visible>

                <label translate="true">Name</label>

            </settings>

        </field>

        <field name="content" sortOrder="20" formElement="input">

            <settings>

                <dataType>text</dataType>

                <visible>true</visible>

                <label translate="true">Content</label>

            </settings>

        </field>

        <field name="title" sortOrder="20" formElement="input">

            <settings>

                <dataType>text</dataType>

                <visible>true</visible>

                <label translate="true">Title</label>

            </settings>

        </field>

    </fieldset>

</form>

Step 15: We need to create a Save.php file

app\code\Vendor\Extension\Block\Adminhtml\Edit\

<?php

namespace Vendor\Extension\Block\Adminhtml\Edit;

use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;

class Save implements ButtonProviderInterface

{

    public function getButtonData()

    {

        return [

            'label' => __('Save'),

            'class' => 'save primary',

            'data_attribute' => [

                'mage-init' => ['button' => ['event' => 'save']],

                'form-role' => 'save',

            ],

            'sort_order' => 90,

        ];

    }

}

Step 16: we will also need to create a Save.php

app\code\Vendor\Extension\Controller\Adminhtml\Index\

<?php

namespace Vendor\Extension\Controller\Adminhtml\Index;

class Save extends \Magento\Backend\App\Action

{

    protected $customFactory;

    protected $adapterFactory;

    protected $uploader;

    public function __construct(

        \Magento\Backend\App\Action\Context $context,

        \Vendor\Extension\Model\CustomFactory $customFactory

    ) {

        parent::__construct($context);

        $this->customFactory = $customFactory;

    }

    public function execute()

    {

        $data = $this->getRequest()->getPostValue();

        try {

            $model = $this->customFactory->create();

$model->addData([

    "name" => $data['name'],

    "content" => $data['content'],

    "title" => $data['title'],

]);

$saveData = $model->save();

if($saveData){

    $this->messageManager->addSuccess( __('Insert data Successfully !') );

}

        }catch (\Exception $e) {

            $this->messageManager->addError(__($e->getMessage()));

        }

        $this->_redirect('*/*/index');

    }

}

Bottom Line

Calling it a day!

In this manner, you can Create UI Component Grid and Form in Magento 2. We anticipate this blog was a beneficial one for you. If you face troubles while executing the code, go ahead and mention them in the comments section below.

Happy Coding!

Click to rate this post!
[Total: 8 Average: 5]
Dhiren Vasoya

Dhiren Vasoya is a Director and Co-founder at MageComp, Passionate 🎖️ Certified Magento Developer👨‍💻. He has more than 9 years of experience in Magento Development and completed 850+ projects to solve the most important E-commerce challenges. He is fond❤️ of coding and if he is not busy developing then you can find him at the cricket ground, hitting boundaries.🏏

View Comments

    • Kindly check Magento log file, is there any error face when you are trying to open the page and show blank screen to you.

  • I get the following error ::

    Argument #2 ($componentData) must be of type array, null given, called in /var/www/html/vendor/magento/framework/View/Element/UiComponentFactory.php on line 221

    • Confirm the code is implemented properly and also run all the Magento commands like upgrade, deploy successfully.

Recent Posts

How to Integrate ChatGPT with Laravel Application?

In this guide, we'll explore how to integrate ChatGPT, an AI-powered chatbot, with a Laravel…

20 hours ago

What are Net Sales? How to Calculate Your Net Sales?

In the world of business, understanding financial metrics is crucial for making informed decisions and…

3 days ago

Magento 2 Extensions Digest April 2024 (New Release & Updates)

Welcome to the MageComp Monthly Digest, where we bring you the latest updates, releases, and…

3 days ago

The ABCs of Geofencing: Definition, Features and Uses

In this era, businesses are always on the lookout for ways to engage with their…

4 days ago

How to Delete Product Variant in a Shopify Remix App using GraphQL Mutations?

Managing a Shopify store efficiently involves keeping your product catalog organized. This includes removing outdated…

5 days ago

6 Innovative Tools Revolutionizing E-Commerce Operations

E-commerce has transformed the way consumers shop for products and services and interact with businesses.…

7 days ago