How to Create Custom Admin Grids in Magento 2

How to Create Custom Admin Grids in Magento 2
If you're diving into Magento 2 development, one of the most common tasks you'll encounter is creating custom admin grids. Whether you're managing custom data, displaying logs, or handling custom entities, a well-structured admin grid is essential for efficient backend management. In this guide, we'll walk you through the process of creating a custom admin grid in Magento 2, step by step. Don't worry if you're new to this—we'll keep it simple and straightforward.
What is an Admin Grid in Magento 2?
An admin grid in Magento 2 is essentially a table that displays data in the backend. It allows admins to view, sort, filter, and manage records easily. Think of it as a dashboard for your custom data. For example, if you're managing a list of custom orders, products, or customer data, an admin grid is the perfect way to organize and interact with that information.
Step 1: Set Up Your Module
Before we dive into creating the grid, let's set up a basic Magento 2 module. If you already have a module, feel free to skip this step.
Create the following directory structure:
app/code/Vendor/Module/
├── etc/
│ ├── module.xml
│ └── adminhtml/
│ ├── routes.xml
├── registration.php
└── view/
└── adminhtml/
├── layout/
└── ui_component/
In app/code/Vendor/Module/etc/module.xml
, add the following code:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_Module" setup_version="1.0.0"/>
</config>
Next, create app/code/Vendor/Module/registration.php
:
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_Module',
__DIR__
);
Finally, create app/code/Vendor/Module/etc/adminhtml/routes.xml
:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="vendor_module" frontName="vendor_module">
<module name="Vendor_Module"/>
</route>
</router>
</config>
Step 2: Create a Database Table
To display data in your grid, you'll need a database table. Let's create a simple table to store custom data.
Create a setup script in app/code/Vendor/Module/Setup/InstallSchema.php
:
<?php
namespace Vendor\Module\Setup;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
class InstallSchema implements InstallSchemaInterface
{
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
$tableName = $installer->getTable('vendor_module_custom_data');
if (!$installer->tableExists($tableName)) {
$table = $installer->getConnection()
->newTable($tableName)
->addColumn(
'entity_id',
Table::TYPE_INTEGER,
null,
[
'identity' => true,
'unsigned' => true,
'nullable' => false,
'primary' => true
],
'Entity ID'
)
->addColumn(
'name',
Table::TYPE_TEXT,
255,
['nullable' => false],
'Name'
)
->addColumn(
'description',
Table::TYPE_TEXT,
'64k',
['nullable' => false],
'Description'
)
->addColumn(
'created_at',
Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => Table::TIMESTAMP_INIT],
'Created At'
)
->setComment('Custom Data Table');
$installer->getConnection()->createTable($table);
}
$installer->endSetup();
}
}
Run the setup upgrade command to create the table:
php bin/magento setup:upgrade
Step 3: Create a Model, Resource Model, and Collection
Next, we need to create a model, resource model, and collection to interact with our database table.
Create the model in app/code/Vendor/Module/Model/Data.php
:
<?php
namespace Vendor\Module\Model;
use Magento\Framework\Model\AbstractModel;
class Data extends AbstractModel
{
protected function _construct()
{
$this->_init(\Vendor\Module\Model\ResourceModel\Data::class);
}
}
Create the resource model in app/code/Vendor/Module/Model/ResourceModel/Data.php
:
<?php
namespace Vendor\Module\Model\ResourceModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class Data extends AbstractDb
{
protected function _construct()
{
$this->_init('vendor_module_custom_data', 'entity_id');
}
}
Create the collection in app/code/Vendor/Module/Model/ResourceModel/Data/Collection.php
:
<?php
namespace Vendor\Module\Model\ResourceModel\Data;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
class Collection extends AbstractCollection
{
protected function _construct()
{
$this->_init(\Vendor\Module\Model\Data::class, \Vendor\Module\Model\ResourceModel\Data::class);
}
}
Step 4: Create the UI Component for the Admin Grid
Now comes the fun part—creating the UI component for the admin grid. This is where Magento 2's powerful UI component system comes into play.
Create the layout file in app/code/Vendor/Module/view/adminhtml/layout/vendor_module_data_index.xml
:
<?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="vendor_module_data_listing"/>
</referenceContainer>
</body>
</page>
Next, create the UI component configuration in app/code/Vendor/Module/view/adminhtml/ui_component/vendor_module_data_listing.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<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">vendor_module_data_listing.vendor_module_data_listing_data_source</item>
<item name="deps" xsi:type="string">vendor_module_data_listing.vendor_module_data_listing_data_source</item>
</item>
<item name="spinner" xsi:type="string">vendor_module_data_columns</item>
</argument>
<dataSource name="vendor_module_data_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Vendor\Module\Model\Data\DataProvider</argument>
<argument name="name" xsi:type="string">vendor_module_data_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_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>
</argument>
</argument>
</dataSource>
<columns name="vendor_module_data_columns">
<column name="entity_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="description">
<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">Description</item>
</item>
</argument>
</column>
<column name="created_at">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">dateRange</item>
<item name="label" xsi:type="string" translate="true">Created At</item>
</item>
</argument>
</column>
</columns>
</listing>
Step 5: Create the Data Provider
The data provider is responsible for fetching data from the database and passing it to the grid. Create the data provider in app/code/Vendor/Module/Model/Data/DataProvider.php
:
<?php
namespace Vendor\Module\Model\Data;
use Magento\Ui\DataProvider\AbstractDataProvider;
use Vendor\Module\Model\ResourceModel\Data\CollectionFactory;
class DataProvider extends AbstractDataProvider
{
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()
{
return $this->collection->toArray();
}
}
Step 6: Add a Menu Item for the Grid
To access your custom grid from the admin panel, you'll need to add a menu item. Create app/code/Vendor/Module/etc/adminhtml/menu.xml
:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="Vendor_Module::custom_data" title="Custom Data" module="Vendor_Module" sortOrder="10" resource="Vendor_Module::custom_data"/>
<add id="Vendor_Module::custom_data_grid" title="Manage Data" module="Vendor_Module" sortOrder="10" parent="Vendor_Module::custom_data" action="vendor_module/data" resource="Vendor_Module::custom_data"/>
</menu>
</config>
Step 7: Create the Controller
Finally, create a controller to handle the grid rendering. Create app/code/Vendor/Module/Controller/Adminhtml/Data/Index.php
:
<?php
namespace Vendor\Module\Controller\Adminhtml\Data;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
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()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->prepend(__('Custom Data'));
return $resultPage;
}
}
Step 8: Test Your Custom Admin Grid
Once everything is set up, log in to your Magento 2 admin panel. You should see a new menu item called "Custom Data" under the main menu. Click on it, and you'll be taken to your custom admin grid, displaying the data from your custom table.
Congratulations! You've successfully created a custom admin grid in Magento 2. From here, you can extend the functionality by adding actions, mass actions, or even inline editing. The possibilities are endless!
If you found this guide helpful, feel free to explore more Magento 2 development tips and tricks on magefine.com. Happy coding!