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

Improving Error Handling and Transition Management in Remix with useRouteError and useViewTransitionState

In modern web development, seamless navigation and state management are crucial for delivering a smooth…

6 days ago

Magento Open Source 2.4.8-Beta Release Notes

Magento Open Source 2.4.8 beta version released on October  8, 2024. The latest release of…

1 week ago

How to Create Catalog Price Rule in Magento 2 Programmatically?

Hello Magento Friends, Creating catalog price rules programmatically in Magento 2 can be a valuable…

1 week ago

Top 10 Tips to Hire Shopify Developers

As the world of eCommerce continues to thrive, Shopify has become one of the most…

2 weeks ago

Managing Browser Events and Navigation in Shopify Remix: useBeforeUnload, useHref, and useLocation Hooks

Shopify Remix is an innovative framework that provides a streamlined experience for building fast, dynamic,…

2 weeks ago

Ultimate Guide to Hiring a Top Shopify Development Agency

Building a successful eCommerce store requires expertise, and for many businesses, Shopify has become the…

2 weeks ago