How to create admin grid in Magento 2 using Layout

I have introduced How to use Event in Magento. To continue Tutorial, I will introduce How to create admin grid in Magento 2 using Layout, it is very importance because when building Magento 2 extension, you can use Admin grid to Manage extension’s data in admin. You can show all items, filter, change, status delete in admin grid.

To Create Admin Grid:

  • Create Router
  • Create Admin menu
  • Create Controller
  • Create Layout

1. Create Router

Create file app/code/Magebay/Hello/etc/adminhtml/routers.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="hello" frontName="hello">
            <module name="Magebay_Hello"/>
        </route>
    </router>
</config>

2. Create Admin menu

Create file app/code/Magebay/Hello/etc/adminhtml/menu.xml

<?xml version="1.0"?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Backend/etc/menu.xsd">
    <menu>
        <add id="Magebay_Hello::hello_menu" title="Magebay Hello" module="Magebay_Hello" sortOrder="20" resource="Magebay_Hello::hello" />
        <add id="Magebay_Hello::posts_menu" title="Magebay Hello" module="Magebay_Hello" sortOrder="1" parent="Magebay_Hello::hello_menu" action="hello/posts/index" resource="Magebay_Hello::posts" />
    </menu>
</config>

how to create admin grid in magento 2 using Layout

3. Create Controller

You can create file Posts.php in app/code/Magebay/Hello/Controller/Adminhtml

<?php

namespace Magebay\Hello\Controller\Adminhtml;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
use Magento\Framework\View\Result\PageFactory;
use Magebay\Hello\Model\PostsFactory;

class Posts extends Action
{
    protected $coreRegistry;
    protected $resultPageFactory;
    protected $postsFactory;
    public function __construct(
        Context $context,
        Registry $coreRegistry,
        PageFactory $resultPageFactory,
        PostsFactory $postsFactory
    ) {
        parent::__construct($context);
        $this->coreRegistry = $coreRegistry;
        $this->resultPageFactory = $resultPageFactory;
        $this->postsFactory = $postsFactory;

    }
    public function execute()
    {

    }

    /**
     * News access rights checking
     *
     * @return bool
     */
    protected function _isAllowed()
    {
        return true;
    }
}

Next , Create index.php in
app/code/Magebay/Hello/Controller/Adminhtml/Posts

<?php

namespace Magebay\Hello\Controller\Adminhtml\Posts;
use Magebay\Hello\Controller\Adminhtml\Posts;
use Magebay\Hello\Model\NewsFactory;
use Magebay\Hello\Model\PostsFactory;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
use Magento\Framework\View\Result\PageFactory;

class Index extends Posts
{
   public function __construct(Context $context, Registry $coreRegistry, PageFactory $resultPageFactory, PostsFactory $postsFactory)
   {
       parent::__construct($context, $coreRegistry, $resultPageFactory, $postsFactory);
   }
   public function execute()
   {
       if ($this->getRequest()->getQuery('ajax')) {
       $this->_forward('grid');
       return;
   }

        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu('Magebay_Hello::hello_menu');
        $resultPage->getConfig()->getTitle()->prepend(__('Manage Posts'));

        return $resultPage;
   }
}

To use function ajax search in Grid, you can create file Grid.php in
app/code/Magebay/Hello/Controller/Adminhtml/Posts

<?php
 
namespace Magebay\Hello\Controller\Adminhtml\Posts;
 
use Magebay\Hello\Controller\Adminhtml\Posts;
class Grid extends Posts
{
   /**
     * @return void
     */
   public function execute()
   {
      return $this->resultPageFactory->create();
   }
}
 

3. Create Layout

The first, You have to create Block for layout, Create file Posts.php in app/code/Magebay/Hello/Block/Adminhtml/Posts.php

<?php

namespace Magebay\Hello\Block;

use Magento\Framework\View\Element\Template;
use Magento\Framework\Registry;

class Posts extends Template
{
    /**
     * Core registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $_coreRegistry;
    

    public function __construct(
        Template\Context $context,
        Registry $coreRegistry,
        array $data = []
    )
    {
        $this->_coreRegistry = $coreRegistry;
        parent::__construct($context, $data);
    }
    
}

Now, you can create 3 files in
app/code/Magebay/Hello/view/adminhtml/layout/

  • file hello_posts_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="formkey"/>
    <update handle="hello_posts_grid_block"/>
    <body>
        <referenceContainer name="content">
            <block class="Magebay\Hello\Block\Adminhtml\Posts" name="hello_posts_grid_block.grid.container" />
        </referenceContainer>
    </body>
</page>
  • file hello_posts_grid.xml
<?xml version="1.0"?>
 
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
    <update handle="formkey"/>
    <update handle="hello_posts_grid_block"/>
    <container name="root">
        <block class="Magento\Backend\Block\Widget\Grid\Container" name="hello_posts_grid_block.grid.container" template="Magento_Backend::widget/grid/container/empty.phtml"/>
    </container>
</layout>
  • file hello_posts_grid_block.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">
    <body>
      <referenceBlock name="hello_posts_grid_block.grid.container">
         <block class="Magento\Backend\Block\Widget\Grid" name="hello_posts_grid_block.grid" as="grid">
             <arguments>
                 <argument name="id" xsi:type="string">news_id</argument>
                 <argument name="dataSource" xsi:type="object">Magebay\Hello\Model\ResourceModel\Posts\Collection</argument>
                 <argument name="default_sort" xsi:type="string">id</argument>
                 <argument name="default_dir" xsi:type="string">ASC</argument>
                 <argument name="save_parameters_in_session" xsi:type="string">1</argument>
             </arguments>
             <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" name="hello_posts_grid_block.grid.columnSet" as="grid.columnSet">
                 <arguments>
                     <argument name="rowUrl" xsi:type="array">
                         <item name="path" xsi:type="string">*/*/edit</item>
                     </argument>
                 </arguments>
                 <block class="Magento\Backend\Block\Widget\Grid\Column" as="post_id">
                     <arguments>
                         <argument name="header" xsi:type="string" translate="true">ID</argument>
                         <argument name="index" xsi:type="string">news_id</argument>
                         <argument name="type" xsi:type="string">text</argument>
                         <argument name="column_css_class" xsi:type="string">col-id</argument>
                         <argument name="header_css_class" xsi:type="string">col-id</argument>
                     </arguments>
                 </block>
                 <block class="Magento\Backend\Block\Widget\Grid\Column" as="status">
                     <arguments>
                         <argument name="header" xsi:type="string" translate="true">Status</argument>
                         <argument name="index" xsi:type="string">status</argument>
                         <argument name="type" xsi:type="string">text</argument>
                         <argument name="column_css_class" xsi:type="string">col-id</argument>
                         <argument name="header_css_class" xsi:type="string">col-id</argument>
                     </arguments>
                 </block>
				  <block class="Magento\Backend\Block\Widget\Grid\Column" as="title">
                     <arguments>
                         <argument name="header" xsi:type="string" translate="true">Title</argument>
                         <argument name="index" xsi:type="string">title</argument>
                         <argument name="type" xsi:type="string">title</argument>
                         <argument name="column_css_class" xsi:type="string">col-id</argument>
                         <argument name="header_css_class" xsi:type="string">col-id</argument>
                     </arguments>
                 </block>
                 <block class="Magento\Backend\Block\Widget\Grid\Column" as="position">
                     <arguments>
                         <argument name="header" xsi:type="string" translate="true">Position</argument>
                         <argument name="index" xsi:type="string">position</argument>
                         <argument name="type" xsi:type="string">position</argument>
                         <argument name="column_css_class" xsi:type="string">col-id</argument>
                         <argument name="header_css_class" xsi:type="string">col-id</argument>
                     </arguments>
                 </block>
                 <block class="Magento\Backend\Block\Widget\Grid\Column" as="updated_at">
                     <arguments>
                         <argument name="header" xsi:type="string" translate="true">Created At</argument>
                         <argument name="index" xsi:type="string">created_at</argument>
                         <argument name="type" xsi:type="string">created_at</argument>
                         <argument name="column_css_class" xsi:type="string">col-id</argument>
                         <argument name="header_css_class" xsi:type="string">col-id</argument>
                     </arguments>
                 </block>
             </block>
         </block>
      </referenceBlock>
    </body>
</page>

Finally, you can go to admin -> Magebay Hello -> Manage Posts you can see result as screen image bellow

how to create admin grid in Magento 2 using Layout

As you can see, Manage data is very importance when building Magento 2 extension. I hope that in this post help you how to create admin grid in Magento 2 using Layout.  I will introduce how to custom grid Grid in Magento 2 extension. if you have any question, you can comment under the post, I will check help you .