Grid and Form in Magento 2 Admin Panel (Part 1)
Hi guys,
In this 6th tutorial, I will introduce you how to create a data grid via Magento 2 backend in custom module. This tutorial is quite long then we will divide it into several parts. We will continue using the Tutorial_SimpleNews module in the last post.
In order to understand this tutorial thoroughly, please review our last tutorials:
1. How to create a simple module in Magento 2
2. Create a module with custom database table in Magento 2
3. How to use Model and Collection in Magento 2
4. How to create the configuration via backend for a custom module
5. Adding new menu item via backend in custom module
Ok, now let’s get started!
Step 1: Create layout files.
- Create file: app/code/Tutorial/SimpleNews/view/adminhtml/layout/simplenews_news_index.xml (Purpose: This file is used to declare grid container block) and insert this following code into it:
<?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="simplenews_news_grid_block"/> <body> <referenceContainer name="content"> <block class="Tutorial\SimpleNews\Block\Adminhtml\News" name="tutorial_simplenews_news.grid.container" /> </referenceContainer> </body> </page>
- Create file: app/code/Tutorial/SimpleNews/view/adminhtml/layout/simplenews_news_grid_block.xml (Purpose: This file is used to declare the content of grid block) and insert this following code into it:
<?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="tutorial_simplenews_news.grid.container"> <block class="Magento\Backend\Block\Widget\Grid" name="tutorial_simplenews_news.grid" as="grid"> <arguments> <argument name="id" xsi:type="string">newsGrid</argument> <argument name="dataSource" xsi:type="object"> Tutorial\SimpleNews\Model\Resource\News\Collection </argument> <argument name="default_sort" xsi:type="string">id</argument> <argument name="default_dir" xsi:type="string">desc</argument> <argument name="save_parameters_in_session" xsi:type="boolean"> true </argument> <argument name="use_ajax" xsi:type="boolean">true</argument> <argument name="grid_url" xsi:type="url" path="*/*/grid"> <param name="_current">1</param> </argument> </arguments> <block class="Magento\Backend\Block\Widget\Grid\Massaction" name="tutorial_simplenews_news.grid.massaction" as="grid.massaction"> <arguments> <argument name="massaction_id_field" xsi:type="string">id</argument> <argument name="form_field_name" xsi:type="string">news</argument> <argument name="options" xsi:type="array"> <item name="delete" xsi:type="array"> <item name="label" xsi:type="string" translate="true"> Delete </item> <item name="url" xsi:type="string">*/*/massDelete</item> <item name="confirm" xsi:type="string" translate="true"> Are you sure you want to delete? </item> </item> </argument> </arguments> </block> <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" name="tutorial_simplenews_news.grid.columnSet" as="grid.columnSet"> <arguments> <argument name="rowUrl" xsi:type="array"> <item name="path" xsi:type="string">*/*/edit</item> <item name="extraParamsTemplate" xsi:type="array"> <item name="id" xsi:type="string">getId</item> </item> </argument> </arguments> <block class="Magento\Backend\Block\Widget\Grid\Column" as="id"> <arguments> <argument name="header" xsi:type="string" translate="true"> ID </argument> <argument name="type" xsi:type="string">number</argument> <argument name="id" xsi:type="string">id</argument> <argument name="index" xsi:type="string">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> </arguments> </block> <block class="Magento\Backend\Block\Widget\Grid\Column" as="summary"> <arguments> <argument name="header" xsi:type="string" translate="true"> Summary </argument> <argument name="index" xsi:type="string">summary</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">options</argument> <argument name="options" xsi:type="options" model="Tutorial\ SimpleNews\Model\System\Config\Status"/> </arguments> </block> <block class="Magento\Backend\Block\Widget\Grid\Column" as="action" acl="Tutorial_SimpleNews::manage_news"> <arguments> <argument name="id" xsi:type="string">action</argument> <argument name="header" xsi:type="string" translate="true"> Action </argument> <argument name="type" xsi:type="string">action</argument> <argument name="getter" xsi:type="string">getId</argument> <argument name="filter" xsi:type="boolean">false</argument> <argument name="sortable" xsi:type="boolean">false</argument> <argument name="index" xsi:type="string">stores</argument> <argument name="is_system" xsi:type="boolean">true</argument> <argument name="actions" xsi:type="array"> <item name="view_action" xsi:type="array"> <item name="caption" xsi:type="string" translate="true"> Edit </item> <item name="url" xsi:type="array"> <item name="base" xsi:type="string">*/*/edit</item> </item> <item name="field" xsi:type="string">id</item> </item> </argument> <argument name="header_css_class" xsi:type="string"> col-actions </argument> <argument name="column_css_class" xsi:type="string"> col-actions </argument> </arguments> </block> </block> </block> </referenceBlock> </body> </page>
- Create file: app/code/Tutorial/SimpleNews/view/adminhtml/layout/simplenews_news_grid.xml (Purpose: This file is used to declare the content of grid when you use ajax to reload the grid) and insert this following code into it:
<?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="simplenews_news_grid_block"/> <container name="root"> <block class="Magento\Backend\Block\Widget\Grid\Container" name="tutorial_simplenews_news.grid.container" template="Magento_Backend::widget/grid/container/empty.phtml"/> </container> </layout>
Step 2: Create News status options file.
- Create file: app/code/Tutorial/SimpleNews/Model/System/Config/Status.php (Purpose: This file is used to get News status options) and insert this following code into it:
<?php namespace Tutorial\SimpleNews\Model\System\Config; use Magento\Framework\Option\ArrayInterface; class Status implements ArrayInterface { const ENABLED = 1; const DISABLED = 0; /** * @return array */ public function toOptionArray() { $options = [ self::ENABLED => __('Enabled'), self::DISABLED => __('Disabled') ]; return $options; } }
Step 3: Create block files.
- Create file: app/code/Tutorial/SimpleNews/Block/Adminhtml/News.php (Purpose: This is the block file of grid container) and insert this following code into it:
<?php namespace Tutorial\SimpleNews\Block\Adminhtml; use Magento\Backend\Block\Widget\Grid\Container; class News extends Container { /** * Constructor * * @return void */ protected function _construct() { $this->_controller = 'adminhtml_news'; $this->_blockGroup = 'Tutorial_SimpleNews'; $this->_headerText = __('Manage News'); $this->_addButtonLabel = __('Add News'); parent::_construct(); } }
- Create file: app/code/Tutorial/SimpleNews/Block/Adminhtml/News/Grid.php (Purpose: This is the block file of grid) and insert this following code into it:
<?php namespace Tutorial\SimpleNews\Block\Adminhtml\News; use Magento\Backend\Block\Widget\Grid as WidgetGrid; class Grid extends WidgetGrid { }
Step 4: Create controller files.
- Create file: app/code/Tutorial/SimpleNews/Controller/Adminhtml/News.php (Purpose: I use this file as a root controller and the action classes will be extended this controller) and insert this following code into it:
<?php namespace Tutorial\SimpleNews\Controller\Adminhtml; use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; use Magento\Framework\Registry; use Magento\Framework\View\Result\PageFactory; use Tutorial\SimpleNews\Model\NewsFactory; class News extends Action { /** * Core registry * * @var \Magento\Framework\Registry */ protected $_coreRegistry; /** * Result page factory * * @var \Magento\Framework\View\Result\PageFactory */ protected $_resultPageFactory; /** * News model factory * * @var \Tutorial\SimpleNews\Model\NewsFactory */ protected $_newsFactory; /** * @param Context $context * @param Registry $coreRegistry * @param PageFactory $resultPageFactory * @param NewsFactory $newsFactory */ public function __construct( Context $context, Registry $coreRegistry, PageFactory $resultPageFactory, NewsFactory $newsFactory ) { parent::__construct($context); $this->_coreRegistry = $coreRegistry; $this->_resultPageFactory = $resultPageFactory; $this->_newsFactory = $newsFactory; } /** * News access rights checking * * @return bool */ protected function _isAllowed() { return $this->_authorization->isAllowed('Tutorial_SimpleNews::manage_news'); } }
- Create file: app/code/Tutorial/SimpleNews/Controller/Adminhtml/News/Index.php (Purpose: This is the index action) and insert this following code into it:
<?php namespace Tutorial\SimpleNews\Controller\Adminhtml\News; use Tutorial\SimpleNews\Controller\Adminhtml\News; class Index extends News { /** * @return void */ 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('Tutorial_SimpleNews::main_menu'); $resultPage->getConfig()->getTitle()->prepend(__('Simple News')); return $resultPage; } }
- Create file: app/code/Tutorial/SimpleNews/Controller/Adminhtml/News/Grid.php (Purpose: This is the grid action which is used for loading grid by ajax) and insert this following code into it:
<?php namespace Tutorial\SimpleNews\Controller\Adminhtml\News; use Tutorial\SimpleNews\Controller\Adminhtml\News; class Grid extends News { /** * @return void */ public function execute() { return $this->_resultPageFactory->create(); } }
Finally, go to backend site then access Simple News > Manage News menu to see your result:
That’s the first part of this tutorial. See you again in the next part, in which I will introduce you how to create a form in Magento 2 Admin Panel.
Enjoy Magento 2 challenge with MageWorld ‘s tutorials! Follow our facebook fanpage for further discussion.