Magento 2 create basic module admin grid part 2

Now we move to second part how in Magento 2 create basic module admin grid. As we cover the main part of module in Magento 2 create basic module part 1. Now we focus on admin part. This tutorial cover the how to create admin controller, how to create admin menu, how to create admin custom ui component grid, how to create admin ui component form,how to create mass action and how to create custom router for admin. So start with creating the router.

Admin Router

Now we define our custom frontName for admin.Now create routes.xml in following directory

QaisarSatti/HelloWorld/etc/adminhtml/

<?xml version="1.0"?>
<!--* Hello World
   *
   * @category    QaisarSatti
   * @package     QaisarSatti_HelloWorld
   * @author      Muhammad Qaisar Satti
   * @Email       qaisarssatti@gmail.com
   *
    -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="helloworld" frontName="helloworld">
            <module name="QaisarSatti_HelloWorld" before="Magento_Backend" />
        </route>
    </router>
</config>

Admin Menu

Now we define our menu for admin.Now create menu.xml in following directory

QaisarSatti/HelloWorld/etc/adminhtml/

<?xml version="1.0"?>
<!--* Hello World
    *
    * @category    QaisarSatti
    * @package     QaisarSatti_HelloWorld
    * @author      Muhammad Qaisar Satti
    * @Email       qaisarssatti@gmail.com
    *
     -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
            <update id="QaisarSatti_HelloWorld::helloworld" title="Qaisar Satti" module="Magento_Backend" sortOrder="177" resource="QaisarSatti_HelloWorld::helloworld"/>
            <add id="QaisarSatti_HelloWorld::helloworldparent" title="Qaisar Satti" module="QaisarSatti_HelloWorld" sortOrder="72"  parent="QaisarSatti_HelloWorld::helloworld" resource="QaisarSatti_HelloWorld::helloworldparent" />
            <add id="QaisarSatti_HelloWorld::helloworld1" title="Manage Blog Post" module="QaisarSatti_HelloWorld" sortOrder="0" parent="QaisarSatti_HelloWorld::helloworldparent" action="helloworld/" resource="QaisarSatti_HelloWorld::helloworld1"/>
    </menu>
</config>

Admin Grid

Now we create custom grid admin.If you want to read the detail about read tutorial Magento 2 create admin controller. Grid is part of three files. Controller file, layout file, grid collection model and ui component file.

Grid Controller

i am creating the grid on my Index.php action. As follow my module create Index.php in following directory

QaisarSatti\HelloWorld\Controller\Adminhtml\Index

<?php
/**
 * Hello World
    *
    * @category    QaisarSatti
    * @package     QaisarSatti_HelloWorld
    * @author      Muhammad Qaisar Satti
    * @Email       qaisarssatti@gmail.com
    *
 */

namespace QaisarSatti\HelloWorld\Controller\Adminhtml\Index;

class Index extends \Magento\Backend\App\Action
{
   
    protected $resultPageFactory;

   
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Registry $coreRegistry,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    ) {
        $this->resultPageFactory = $resultPageFactory;
        parent::__construct($context, $coreRegistry);
    }

   
    public function execute()
    {

        $resultPage = $this->resultPageFactory->create();
        $this->initPage($resultPage)->getConfig()->getTitle()->prepend(__('Manage Post'));
        return $resultPage;
    }
    protected function initPage($resultPage)
    {
         $resultPage->setActiveMenu('QaisarSatti_HelloWorld::helloworld1')
             ->addBreadcrumb(__('Qaisar Satti'), __('Qaisar Satti'))
             ->addBreadcrumb(__('Manage Post'), __('Manage Post'));

         return $resultPage;
    }

 
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('QaisarSatti_HelloWorld::helloworld1');
    }
}

Grid layout

Now we create the grid layout file that connect it with ui component. Our ui component file name is helloworld_listing. So create helloworld_index_index.xml in following directory

QaisarSatti\HelloWorld\view\adminhtml\layout

<?xml version="1.0"?>
<!--
   /**
   * Hello World
   *
   * @category    QaisarSatti
   * @package     QaisarSatti_HelloWorld
   * @author      Muhammad Qaisar Satti
   * @Email       qaisarssatti@gmail.com
   *
*/
-->
<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="helloworld_listing"/>
        </referenceContainer>
     
    </body>
</page>

Grid Collection Model

For the grid you need to create grid collection model.This collection have method that used for grid. Create Collection.php in following directory

QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld\Grid\

<?php
/**
 * Hello World
    *
    * @category    QaisarSatti
    * @package     QaisarSatti_HelloWorld
    * @author      Muhammad Qaisar Satti
    * @Email       qaisarssatti@gmail.com
    *
 */

namespace QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld\Grid;

use Magento\Framework\Api\Search\SearchResultInterface;
use Magento\Framework\Api\Search\AggregationInterface;
use QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld\Collection as HelloWorldCollection;

/**
 * Class Collection
 * Collection for displaying grid of sales documents
 */

class Collection extends HelloWorldCollection implements SearchResultInterface
{
    /**
     * @var AggregationInterface
     */

    protected $aggregations;

    /**
     * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
     * @param \Magento\Framework\Event\ManagerInterface $eventManager
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
     * @param mixed|null $mainTable
     * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $eventPrefix
     * @param mixed $eventObject
     * @param mixed $resourceModel
     * @param string $model
     * @param null $connection
     * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource
     *
     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
     */

    public function __construct(
        \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\EntityManager\MetadataPool $metadataPool,
        $mainTable,
        $eventPrefix,
        $eventObject,
        $resourceModel,
        $model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
        $connection = null,
        \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
    ) {
        parent::__construct(
            $entityFactory,
            $logger,
            $fetchStrategy,
            $eventManager,
            $storeManager,
            $metadataPool,
            $connection,
            $resource
        );
        $this->_eventPrefix = $eventPrefix;
        $this->_eventObject = $eventObject;
        $this->_init($model, $resourceModel);
        $this->setMainTable($mainTable);
    }

    /**
     * @return AggregationInterface
     */

    public function getAggregations()
    {
        return $this->aggregations;
    }

    /**
     * @param AggregationInterface $aggregations
     * @return $this
     */

    public function setAggregations($aggregations)
    {
        $this->aggregations = $aggregations;
    }

    /**
     * Get search criteria.
     *
     * @return \Magento\Framework\Api\SearchCriteriaInterface|null
     */

    public function getSearchCriteria()
    {
        return null;
    }

    /**
     * Set search criteria.
     *
     * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
     * @return $this
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */

    public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null)
    {
        return $this;
    }

    /**
     * Get total count.
     *
     * @return int
     */

    public function getTotalCount()
    {
        return $this->getSize();
    }

    /**
     * Set total count.
     *
     * @param int $totalCount
     * @return $this
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */

    public function setTotalCount($totalCount)
    {
        return $this;
    }

    /**
     * Set items list.
     *
     * @param \Magento\Framework\Api\ExtensibleDataInterface[] $items
     * @return $this
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */

    public function setItems(array $items = null)
    {
        return $this;
    }
}

Define Data Source and Data Provider

Now we define data source for grid. Our dataSource name will be helloworld_listing_data_source and DataProvider name helloworldGridDataProvider.create di.xml in following directory

QaisarSatti\HelloWorld\etc\\

<?xml version="1.0"?>
<!--
/**
* Hello World
   *
   * @category    QaisarSatti
   * @package     QaisarSatti_HelloWorld
   * @author      Muhammad Qaisar Satti
   * @Email       qaisarssatti@gmail.com
   *
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="helloworld_listing_data_source" xsi:type="string">QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
    <type name="QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld\Grid\Collection">
        <arguments>
            <argument name="mainTable" xsi:type="string">sample_posts</argument>
            <argument name="eventPrefix" xsi:type="string">helloworld_grid_collection</argument>
            <argument name="eventObject" xsi:type="string">helloworld_grid_collection</argument>
            <argument name="resourceModel" xsi:type="string">QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld</argument>
        </arguments>
    </type>
    <virtualType name="helloworldGirdFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
        <arguments>
            <argument name="appliers" xsi:type="array">
                <item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
                <item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
            </argument>
        </arguments>
    </virtualType>
     <virtualType name="helloworldGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
        <arguments>
            <argument name="collection" xsi:type="object" shared="false">QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld\Collection</argument>
            <argument name="filterPool" xsi:type="object" shared="false">helloworldGirdFilterPool</argument>
        </arguments>
    </virtualType>
   
 
</config>

Grid Action Column Url Builder

create UrlBuilder.php in following directory

QaisarSatti\HelloWorld\Block\Adminhtml\HelloWorld\Grid\Renderer\Action\

<?php
/**
 * Hello World
    *
    * @category    QaisarSatti
    * @package     QaisarSatti_HelloWorld
    * @author      Muhammad Qaisar Satti
    * @Email       qaisarssatti@gmail.com
    *
 */

namespace QaisarSatti\HelloWorld\Block\Adminhtml\HelloWorld\Grid\Renderer\Action;

class UrlBuilder
{
    /**
     * @var \Magento\Framework\UrlInterface
     */

    protected $frontendUrlBuilder;

    /**
     * @param \Magento\Framework\UrlInterface $frontendUrlBuilder
     */

    public function __construct(\Magento\Framework\UrlInterface $frontendUrlBuilder)
    {
        $this->frontendUrlBuilder = $frontendUrlBuilder;
    }

    /**
     * Get action url
     *
     * @param string $routePath
     * @param string $scope
     * @param string $store
     * @return string
     */

    public function getUrl($routePath, $scope, $store)
    {
        $this->frontendUrlBuilder->setScope($scope);
        $href = $this->frontendUrlBuilder->getUrl(
            $routePath,
            ['_current' => false, '_query' => '___store=' . $store]
        );
        return $href;
    }
}

Grid Action Column

This will be used in action column of grid. You can add edit or any action you want to perform with current row data. create HelloWorldActions.php in following directory

QaisarSatti\HelloWorld\Ui\Component\Listing\Column\

<?php
/**
 * Hello World
    *
    * @category    QaisarSatti
    * @package     QaisarSatti_HelloWorld
    * @author      Muhammad Qaisar Satti
    * @Email       qaisarssatti@gmail.com
    *
 */

namespace QaisarSatti\HelloWorld\Ui\Component\Listing\Column;

use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use QaisarSatti\HelloWorld\Block\Adminhtml\HelloWorld\Grid\Renderer\Action\UrlBuilder;
use Magento\Framework\UrlInterface;

/**
 * Class PageActions
 */

class HelloWorldActions extends Column
{
    /** Url path */
    const HELLOWORLD_URL_PATH_EDIT = 'helloworld/index/edit';
    const HELLOWORLD_URL_PATH_DELETE = 'helloworld/index/delete';

    /** @var UrlBuilder */
    protected $actionUrlBuilder;

    /** @var UrlInterface */
    protected $urlBuilder;

    /**
     * @var string
     */

    private $editUrl;

    /**
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param UrlBuilder $actionUrlBuilder
     * @param UrlInterface $urlBuilder
     * @param array $components
     * @param array $data
     * @param string $editUrl
     */

    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        UrlBuilder $actionUrlBuilder,
        UrlInterface $urlBuilder,
        array $components = [],
        array $data = [],
        $editUrl = self::HELLOWORLD_URL_PATH_EDIT
    ) {
        $this->urlBuilder = $urlBuilder;
        $this->actionUrlBuilder = $actionUrlBuilder;
        $this->editUrl = $editUrl;
        parent::__construct($context, $uiComponentFactory, $components, $data);
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */

    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {
                $name = $this->getData('name');
                if (isset($item['post_id'])) {
                    $item[$name]['edit'] = [
                        'href' => $this->urlBuilder->getUrl($this->editUrl, ['id' => $item['post_id']]),
                        'label' => __('Edit')
                    ];
                    $item[$name]['delete'] = [
                        'href' => $this->urlBuilder->getUrl(self::HELLOWORLD_URL_PATH_DELETE, ['id' => $item['post_id']]),
                        'label' => __('Delete'),
                        'confirm' => [
                            'title' => __('Delete ${ $.$data.title }'),
                            'message' => __('Are you sure you wan\'t to delete a ${ $.$data.title } record?')
                        ]
                    ];
 
                }
            }

        return $dataSource;
        }
    }
}

Grid Ui Component

I already posted the detail article about Magento 2 create custom ui component admin grid. So we not going to detail explanation about it. So move on with create helloworld_listing.xml in following directory

QaisarSatti\HelloWorld\view\adminhtml\ui_component\

<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Hello World
   *
   * @category    QaisarSatti
   * @package     QaisarSatti_HelloWorld
   * @author      Muhammad Qaisar Satti
   * @Email       qaisarssatti@gmail.com
   *
*/
-->
<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">helloworld_listing.helloworld_listing_data_source</item>
            <item name="deps" xsi:type="string">helloworld_listing.helloworld_listing_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">helloworld_index_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 Blog Post</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/new</item>
            </item>
        </item>
    </argument>
    <dataSource name="helloworld_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">helloworldGridDataProvider</argument>
            <argument name="name" xsi:type="string">helloworld_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">post_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>
    <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">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="columnsProvider" xsi:type="string">helloworld_listing.helloworld_listing.helloworld_index_columns</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">storageConfig.storageConfig.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.filters</item>
                    </item>
                    <item name="templates" xsi:type="array">
                        <item name="filters" xsi:type="array">
                            <item name="select" xsi:type="array">
                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
                                <item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
                            </item>
                        </item>
                    </item>
                    <item name="childDefaults" xsi:type="array">
                        <item name="provider" xsi:type="string">storageConfig.storageConfig.listing_top.listing_filters</item>
                        <item name="imports" xsi:type="array">
                            <item name="visible" xsi:type="string">storageConfig.storageConfig.helloworld_index_columns.${ $.index }:visible</item>
                        </item>
                    </item>
                </item>
                <item name="observers" xsi:type="array">
                    <item name="column" xsi:type="string">column</item>
                </item>
            </argument>
        </filters>
        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">helloworld_listing.helloworld_listing.helloworld_index_columns.ids</item>
                    <item name="indexField" xsi:type="string">post_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="helloworld/index/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 wan't to delete selected items?</item>
                        </item>
                    </item>
                </argument>
            </action>
        </massaction>
        <paging name="listing_paging"/>
    </listingToolbar>
   
    <columns name="helloworld_index_columns">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="storageConfig" xsi:type="array">
                    <item name="provider" xsi:type="string">helloworld_listing.helloworld_listing.listing_top.bookmarks</item>
                    <item name="namespace" xsi:type="string">current</item>
                </item>
                <item name="editorConfig" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">helloworld_listing.helloworld_listing.helloworld_index_columns.ids</item>
                    <item name="enabled" xsi:type="boolean">true</item>
                    <item name="indexField" xsi:type="string">id</item>
                    <item name="clientConfig" xsi:type="array">
                        <item name="saveUrl" xsi:type="url" path="news/index/inlineEdit"/>
                        <item name="validateBeforeSave" xsi:type="boolean">false</item>
                    </item>
                </item>
                <item name="childDefaults" xsi:type="array">
                    <item name="fieldAction" xsi:type="array">
                        <item name="provider" xsi:type="string">helloworld_listing.helloworld_listing.helloworld_index_columns_editor</item>
                        <item name="target" xsi:type="string">startEdit</item>
                        <item name="params" xsi:type="array">
                            <item name="0" xsi:type="string">${ $.$data.rowIndex }</item>
                            <item name="1" xsi:type="boolean">true</item>
                        </item>
                    </item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">helloworld_listing.helloworld_listing.listing_top.bookmarks</item>
                        <item name="root" xsi:type="string">columns.${ $.index }</item>
                        <item name="namespace" xsi:type="string">current.${ $.storageConfig.root}</item>
                    </item>
                </item>
            </item>
        </argument>
        <selectionsColumn name="ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">55</item>
                    <item name="indexField" xsi:type="string">post_id</item>
                </item>
            </argument>
        </selectionsColumn>
        <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="editor" xsi:type="array">
                        <item name="editorType" xsi:type="string">text</item>
                        <item name="validation" xsi:type="array">
                            <item name="required-entry" xsi:type="boolean">true</item>
                        </item>
                    </item>
                    <item name="label" xsi:type="string" translate="true">Title</item>
                </item>
            </argument>
        </column>
         <column name="content">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="editor" xsi:type="array">
                        <item name="editorType" xsi:type="string">textarea</item>
                        <item name="validation" xsi:type="array">
                            <item name="required-entry" xsi:type="boolean">true</item>
                        </item>
                    </item>
                    <item name="label" xsi:type="string" translate="true">Content</item>
                </item>
            </argument>
        </column>  
        <actionsColumn name="actions" class="QaisarSatti\HelloWorld\Ui\Component\Listing\Column\HelloWorldActions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">107</item>
                    <item name="indexField" xsi:type="string">post_id</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
    <container name="sticky">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/grid/sticky/sticky</item>
                <item name="toolbarProvider" xsi:type="string">helloworld_listing.helloworld_listing.listing_top</item>
                <item name="listingProvider" xsi:type="string">helloworld_listing.helloworld_listing.helloworld_index_columns</item>
            </item>
        </argument>
    </container>
</listing>

Grid Mass Action

Now we create the mass action controller for grid. You can any mass action like enabled, disabled and any other mass action. Now i am creating mass delete action. Create controller for MassDelete.php in following directory

QaisarSatti\HelloWorld\Controller\Adminhtml\Index\

<?php
/**
 * Hello World
    *
    * @category    QaisarSatti
    * @package     QaisarSatti_HelloWorld
    * @author      Muhammad Qaisar Satti
    * @Email       qaisarssatti@gmail.com
    *
 */

namespace QaisarSatti\HelloWorld\Controller\Adminhtml\Index;

use Magento\Framework\Controller\ResultFactory;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld\CollectionFactory;

class MassDelete extends \Magento\Backend\App\Action
{
    /**
     * @var Filter
     */

    protected $filter;

    /**
     * @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 \Magento\Backend\Model\View\Result\Redirect
     * @throws \Magento\Framework\Exception\LocalizedException|\Exception
     */

    public function execute()
    {
        $collection = $this->filter->getCollection($this->collectionFactory->create());
        $collectionSize = $collection->getSize();

        foreach ($collection as $page) {
            $page->delete();
        }

        $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $collectionSize));

        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
        return $resultRedirect->setPath('*/*/');
    }
}

Now we complete the custom admin grid. Now move to third part Magento 2 create basic module admin from part 3.

Qaisar Satti

Hi, I'm Qaisar Satti! I've been a developer for over 20 years, and now I love sharing what I've learned through tutorials and guides. Whether you're working with Magento, PrestaShop, or WooCommerce, my goal is to make your development journey a bit easier and more fun. When I'm not coding or writing, you can find me exploring new tech trends and hanging out with the amazing developer community. Thanks for stopping by, and happy coding!

Leave a Reply