How to Create UI Component Grid and Form in Magento 2

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!

Previous Article

How to Start Dropshipping With Shopify (The Definitive Guide)

Next Article

Guide to Implement Autocomplete Address Field in Magento 2

Write a Comment
  1. raoul guillermo

    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

Leave a Comment

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

Get Connect With Us

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨