Creating a backend data grid

Adding a page to the backend requires, just like the frontend, a configured route, controller, and layout file. In order to display a grid page to show data from a table, there are currently three ways available:

  • Creating a grid container and specifying the fields to display and data source to use in the grid class. This method is similar to how a grid is built in Magento 1 and is not really flexible/easy to extend. An example of how this is used can be found in the CMS Page module:

    MagentoCmsBlockAdminhtmlPage

    MagentoCmsBlockAdminhtmlPageGrid

  • Using this method, there is only a grid container Block class created. The grid fields and options are defined in the layout XML file. This makes it possible to extend the grid easily by adding extra fields to the XML. An example of this can be found in the Customer Group code in the following:

    MagentoCustomerviewadminhtmllayoutcustomer_group_index.xml

  • The last option is fully configured through XML and gives the option to specify the data source, quick search, available advanced filters, mass actions, row actions, and columns to show. It also gives you the option to customize the columns shown in the backend by the user.

In this example, we will use the last option to build a grid. As this option uses quite a large set of files and long XML listings, the complete code can be found on GitHub (https://github.com/Genmato/M2_Sample).

How to do it…

The following steps will describe how to add a backend data grid:

  1. Configure routes for use in the adminhtml area:

    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="sample" frontName="sample">
          <module name="Genmato_Sample" before="Magento_Backend" />
        </route>
      </router>
    </config>
  2. Create the Controller for the backend:

    Controller/Adminhtml/Demolist/Index.php

    <?php
    namespace GenmatoSampleControllerAdminhtmlDemolist;
    
    use MagentoBackendAppActionContext;
    use MagentoFrameworkViewResultPageFactory;
    use MagentoBackendAppAction as BackendAction;
    
    class Index extends BackendAction
    {
      /**
      * @var PageFactory
      */
      protected $resultPageFactory;
    
      /**
      * @param Context $context
      * @param PageFactory $resultPageFactory
      */
      public function __construct(
        Context $context,
        PageFactory $resultPageFactory
      ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
      }
      /**
      * Check the permission to run it
      *
      * @return bool
      */
      protected function _isAllowed()
      {
        return $this->_authorization->isAllowed('Genmato_Sample::demolist');
      }
    
      /**
      * Index action
      *
      * @return MagentoBackendModelViewResultPage
      */
      public function execute()
      {
        /** @var MagentoBackendModelViewResultPage $resultPage */
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu('Genmato_Sample::demolist');
        $resultPage->addBreadcrumb(__('CMS'), __('CMS'));
        $resultPage->addBreadcrumb(__('Demo List'), __('Demo List'));
        $resultPage->getConfig()->getTitle()->prepend(__('Demo List'));
    
        return $resultPage;
      }
    }
  3. Control the access to the page through the ACL:

    etc/acl.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
      <acl>
        <resources>
          <resource id="Magento_Backend::admin">
            <resource id="Magento_Backend::content">
              <resource id="Magento_Backend::content_elements">
                <resource id="Genmato_Sample::demolist" title="Demo List" sortOrder="10" />
              </resource>
            </resource>
          </resource>
        </resources>
      </acl>
    </config>
  4. The following is the layout file to specify the grid uiComponent used:

    view/adminhtml/layout/sample_demolist_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">
      <update handle="styles"/>
      <body>
        <referenceContainer name="content">
          <uiComponent name="sample_demolist_listing"/>
        </referenceContainer>
      </body>
    </page>
  5. Create the uiComponent configuration:

    The referenced uiComponent configuration is quite large. In the sample code (on GitHub), this file can be found at the following:

    https://github.com/mage2cookbook/M2_Sample/blob/master/view/adminhtml/ui_component/sample_demolist_listing.xml

  6. Add resources used in uiComponent to the dependency injection configuration:

    etc/di.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <preference for="GenmatoSampleModelDemoInterface" type="GenmatoSampleModelDemo" />
    
      <type name="MagentoFrameworkViewElementUiComponentDataProviderCollectionFactory">
        <arguments>
          <argument name="collections" xsi:type="array">
            <item name="sample_demolist_listing_data_source" xsi:type="string">GenmatoSampleModelResourceModelDemoGridCollection</item>
          </argument>
        </arguments>
      </type>
      <type name="GenmatoSampleModelResourceModelDemoGridCollection">
        <arguments>
          <argument name="mainTable" xsi:type="string">genmato_demo</argument>
          <argument name="eventPrefix" xsi:type="string">sample_demolist_grid_collection</argument>
          <argument name="eventObject" xsi:type="string">sample_demolist_collection</argument>
          <argument name="resourceModel" xsi:type="string">GenmatoSampleModelResourceModelDemo</argument>
        </arguments>
      </type>
      <virtualType name="DemoGridFilterPool" type="MagentoFrameworkViewElementUiComponentDataProviderFilterPool">
        <arguments>
          <argument name="appliers" xsi:type="array">
            <item name="regular" xsi:type="object">MagentoFrameworkViewElementUiComponentDataProviderRegularFilter</item>
            <item name="fulltext" xsi:type="object">MagentoFrameworkViewElementUiComponentDataProviderFulltextFilter</item>
          </argument>
        </arguments>
      </virtualType>
      <virtualType name="DemoGridDataProvider" type="MagentoFrameworkViewElementUiComponentDataProviderDataProvider">
        <arguments>
          <argument name="collection" xsi:type="object" shared="false">GenmatoSampleModelResourceModelDemoCollection</argument>
          <argument name="filterPool" xsi:type="object" shared="false">DemoGridFilterPool</argument>
        </arguments>
      </virtualType>
    </config>
  7. Add the mass action controller:

    Controller/Adminhtml/Demolist/MassDelete.php

    <?php
    namespace GenmatoSampleControllerAdminhtmlDemolist;
    
    use MagentoFrameworkControllerResultFactory;
    use MagentoBackendAppActionContext;
    use MagentoUiComponentMassActionFilter;
    use GenmatoSampleModelResourceModelDemoCollectionFactory;
    use MagentoBackendAppAction;
    
    class MassDelete extends Action
    {
    
      /**
      * @var CollectionFactory
      */
      protected $collectionFactory;
    
      /**
      * @param Context $context
      * @param Filter $filter
      * @param CollectionFactory $collectionFactory
      */
      public function __construct(Context $context, Filter $filter, CollectionFactory $collectionFactory)
      {
        $this->filter = $filter;
        $this->collectionFactory = $collectionFactory;
        parent::__construct($context);
      }
    
      /**
      * Execute action
      *
      * @return MagentoBackendModelViewResultRedirect
      */
      public function execute()
      {
        $collection = $this->filter->getCollection($this->collectionFactory->create());
        $collectionSize = $collection->getSize();
    
        foreach ($collection as $item) {
          $item->delete();
        }
    
        $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $collectionSize));
    
        /** @var MagentoBackendModelViewResultRedirect $resultRedirect */
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
        return $resultRedirect->setPath('*/*/');
      }
    }
  8. Add options to the menu:

    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="Genmato_Sample::demolist" title="Demo List" module="Genmato_Sample" sortOrder="10" parent="Magento_Backend::content_elements" action="sample/demolist" resource="Genmato_Sample::demolist"/>
      </menu>
    </config>

How it works…

The controller and layout file are the same for the frontend, only the backend is protected through an ACL. This allows administrators to create specific user rules and allow access only to the selected pages.

The resource access is checked in the controller in the following function:

protected function _isAllowed()

The uiComponent configuration

As the complete configuration through uiComponent results in a large XML file, we will explain some parts on how they are configured and hook in to the system.

Data source

The data source is specified through the XML node:

<listing>
<dataSource name="sample_demolist_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">DemoGridDataProvider</argument>

The specified data class, DemoGridDataProvider, is configured through dependency injection and specified in the etc/di.xml file. Here, DemoGridDataProvider corresponds to the GenmatoSampleModelResourceModelDemoCollection collection. Additionally, DemoGridFilterPool and the collection are configured through this file to load the data.

Mass actions for grid

It is also easy to specify multiple mass actions to be used in the grid; you can specify the title, action to execute, and optional message alert box:

<massaction name="listing_massaction">
  <argument name="data" xsi:type="array">
    <item name="config" xsi:type="array">
      <item name="selectProvider" xsi:type="string">sample_demolist_listing.sample_demolist_listing.sample_demolist_columns.ids</item>
      <item name="indexField" xsi:type="string">demo_id</item>
    </item>
  </argument>
  <action name="delete">
    <argument name="data" xsi:type="array">
      <item name="config" xsi:type="array">
        <item name="type" xsi:type="string">delete</item>
        <item name="label" xsi:type="string" translate="true">Delete</item>
        <item name="url" xsi:type="url" path="sample/demolist/massDelete"/>
        <item name="confirm" xsi:type="array">
          <item name="title" xsi:type="string" translate="true">Delete items</item>
          <item name="message" xsi:type="string" translate="true">Are you sure you want to delete selected items?</item>
        </item>
      </item>
    </argument>
  </action>
</massaction>

In this example, we add an option to delete records from the database. In order to delete the records from the database, you need to create a controller that handles the removal of the records. You need to create a Controller class for every action you specify, this controller contains your custom code to be executed.

By adding the menu option in the Content menu below the Pages menu item, the page can be accessed through the backend. This link action will go to the specified sample/demolist URL that will result in the full URL:

http://example.com/admin/sample/demolist/

The resource argument defines the ACL that is used to show/hide the menu option depending on the user rights:

Mass actions for grid

When clicking on the menu option, the resulting page will look as follows:

Mass actions for grid

See also

For more information about uiComponents that are available, you can refer to the following:

http://devdocs.magento.com/guides/v2.0/ui-components/ui-component.html

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.146.176.145