SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH
mass-action

How to add Mass Action in admin grid in Magento 2

When I started learning about create admin grid, every time I want to delete a number of rows, I have to into each row to delete one by one. Therefore, it’s really annoying to delete or enable/disable plenty of rows.

But with mass actions, you can conveniently take actions on them.

And to be clear that what I about to instructing down here only focuses on how to create mass actions, not how to create an admin grid.

File Structure

Those files contained in red will appear in this section and it’s needed to build up mass actions.

Admin Grid File

Below is code in vendor_module_rule_index.xml in pathVendor\Module\view\adminhtml\layout which is the layout file of the admin grid.

<?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">
        <block class="Vendor\Module\Block\Adminhtml\Rule" name="adminhtml.block.rule.grid.container">
            <block class="Magento\Backend\Block\Widget\Grid" name="adminhtml.block.rule.grid" as="grid">
                <arguments>
                    <argument name="id" xsi:type="string">grid</argument>
                    <argument name="dataSource" xsi:type="object">Vendor\Module\Model\ResourceModel\Rule\Collection</argument>
                    <argument name="default_sort" xsi:type="string">sort_order</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\Massaction"
                       name="adminhtml.block.rule.grid.massaction" as="grid.massaction">
                        <arguments>
                            <argument name="massaction_id_field" xsi:type="string">rule_id</argument>
                            <argument name="form_field_name" xsi:type="string">rule_ids</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">vendor_module/rule/MassDelete</item>
                                    <item name="confirm" xsi:type="string" translate="true">Are you sure you want to delete?</item>
                                </item>
                                <item name="activate" xsi:type="array">
                                    <item name="label" xsi:type="string" translate="true">Activate</item>
                                    <item name="url" xsi:type="string">vendor_module/rule/MassActivate</item>
                                    <item name="confirm" xsi:type="string" translate="true">Are you sure you want to activate?</item>
                                </item>
                                <item name="inactivate" xsi:type="array">
                                    <item name="label" xsi:type="string" translate="true">InActivate</item>
                                    <item name="url" xsi:type="string">vendor_module/rule/MassInActivate</item>
                                    <item name="confirm" xsi:type="string" translate="true">Are you sure you want to inactivate?</item>
                                </item>
                            </argument>
                        </arguments>
                </block>

                <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" as="grid.columnSet" name="adminhtml.example.rule.grid.columnSet">
                    <arguments>
                        <argument name="rowUrl" xsi:type="array">
                            <item name="path" xsi:type="string">vendor_module/*/edit</item>
                            <item name="extraParamsTemplate" xsi:type="array">
                                <item name="id" xsi:type="string">getRuleId</item>
                            </item>
                        </argument>
                    </arguments>
                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="rule_id">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">ID</argument>
                            <argument name="index" xsi:type="string">rule_id</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="name">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Rule</argument>
                            <argument name="index" xsi:type="string">name</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="array">
                                <item name="active" xsi:type="array">
                                    <item name="value" xsi:type="string">1</item>
                                    <item name="label" xsi:type="string" translate="true">Active</item>
                                </item>
                                <item name="inactive" xsi:type="array">
                                    <item name="value" xsi:type="string">0</item>
                                    <item name="label" xsi:type="string" translate="true">Inactive</item>
                                </item>
                            </argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="priority">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Priority</argument>
                            <argument name="index" xsi:type="string">priority</argument>
                        </arguments>
                    </block>
                </block>
            </block>
        </block>
    </referenceContainer>
    </body>
</page>

You can see there are lines write about Massaction. Pay attention to the lines start from: <block class="Magento\Backend\Block\Widget\Grid\Massaction"
name="adminhtml.block.rule.grid.massaction" as="grid.massaction"> and it's arguments
.

Argument name massaction_id_field is one of the fields in your model. I chose field rule_id to be my massaction_id_field.

And argument form_field_name is a variable that will contain an array of rule_id. You will know how to get it in the controller files below.

In argument options, there are three items label name delete, activate, and inactivate. These three are three different mass actions with functions just like their name.

Create Vendor\Module\Controller\Adminhtml\Rule.php

Other files in Vendor\Module\Controller\Adminhtml\Rule path will extends this file.

<?php
namespace Vendor\Module\Controller\Adminhtml;

abstract class Rule extends \Magento\Backend\App\Action
{
    /**
     * Core registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $coreRegistry = null;

    /**
     * @var \Magento\Framework\App\Response\Http\FileFactory
     */
    protected $fileFactory;

    /**
     * @var \Magento\Framework\Stdlib\DateTime\Filter\Date
     */
    protected $dateFilter;

    /**
     * @var \Vendor\Module\Model\RuleFactory
     */
    protected $ruleFactory
;

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;
    protected $responsive;
    protected $json;
    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Framework\Registry $coreRegistry
     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
     * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter
     * @param \Vendor\Module\Model\RuleFactory $ruleFactory
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Registry $coreRegistry,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter,
        \Vendor\Module\Model\RuleFactory $ruleFactory
,
        \Psr\Log\LoggerInterface $logger


    ) {
        parent::__construct($context);
        $this->coreRegistry = $coreRegistry;
        $this->fileFactory = $fileFactory;
        $this->dateFilter = $dateFilter;
        $this->ruleFactory
= $ruleFactory
;
        $this->logger = $logger;
    }

    /**
     * Initiate rule
     *
     * @return void
     */
    protected function _initRule()
    {
        $rule = $this->categoriesFactory->create();
        $this->coreRegistry->register(
            'rule_massaction',
            $rule
        );
        $id = (int)$this->getRequest()->getParam('id');

        if (!$id && $this->getRequest()->getParam('rule_id')) {
            $id = (int)$this->getRequest()->getParam('rule_id');
        }

        if ($id) {
            $this->coreRegistry->registry('rule_massaction')->load($id);
        }
    }

}

Controller Of Mass Action Delete

And in case you’ve really understood the URL path: vendor_module/rule/MassActivate. This Url is base on 3 parts: frontname + folder in path Vendor\Module\Controller\Adminhtml contained mass action controller file + mass action controller file name.

<?php
namespace Vendor\Module\Controller\Adminhtml\Rule;
class MassDelete extends \Vendor\Module\Controller\Adminhtml\Rule
{
    public function execute()
    {
        $ruleIds = $this->getRequest()->getParam('rule_ids', array()); /*get form_field_name argument variable*/
        if(!is_array($ruleIds))$ruleIds=explode(",",$ruleIds);
        $model = $model = $this->ruleFactory->create();
        if(count($ruleIds))
        {
            $i = 0;
            foreach ($ruleIds as $ruleId) {
                try {
                    $model->load($ruleId);
                    $model->delete();
                    $i++;
                } catch (\Exception $e) {
                    $this->messageManager->addErrorMessage($e->getMessage());
                }
            }
            if ($i > 0) {
                $this->messageManager->addSuccessMessage(
                    __('A total of %1 item(s) were deleted.', $i)
                );
            }
        }
        else
        {
            $this->messageManager->addErrorMessage(
                __('You can not delete item(s), Please check again %1')
            );
        }
        $this->_redirect('*/*/index');
    }
}

Controller Of Mass Action Activate

<?php
namespace Vendor\Module\Controller\Adminhtml\Rule;
class MassActivate extends \Vendor\Module\Controller\Adminhtml\Rule
{
    public function execute()
    {   
        $ruleIds = $this->getRequest()->getParam('rule_ids', array());
        if(!is_array($ruleIds))$ruleIds=explode(",",$ruleIds);
        $model = $this->ruleFactory->create();
        if(count($ruleIds))
        {
            $i = 0;
            foreach ($ruleIds as $ruleId) {
                try {
                    $model->load($ruleId);
                    $model->setData('status','1'); /*status = 1 is Activate, = 0 is InActivate*/
                    $model->save();
                    $i++;
                } catch (\Exception $e) {
                    $this->messageManager->addErrorMessage($e->getMessage());
                }
            }
            if ($i > 0) {
                $this->messageManager->addSuccessMessage(
                    __('A total of %1 item(s) were activated.', $i)
                );
            }
        }
        else
        {
            $this->messageManager->addErrorMessage(
                __('You can not activate item(s), Please check again %1')
            );
        }
        $this->_redirect('*/*/index');
    }
}

Controller Of Mass Action InActivate

<?php
namespace Vendor\Module\Controller\Adminhtml\Rule;
class MassInActivate extends \Vendor\Module\Controller\Adminhtml\Rule
{
    public function execute()
    {   
        $ruleIds = $this->getRequest()->getParam('rule_ids', array());
        if(!is_array($ruleIds))$ruleIds=explode(",",$ruleIds);
        $model = $model = $this->ruleFactory->create();
        if(count($ruleIds))
        {
            $i = 0;
            foreach ($ruleIds as $ruleId) {
                try {
                    $model->load($ruleId);
                    $model->setData('status','0');
                    $model->save();
                    $i++;
                } catch (\Exception $e) {
                    $this->messageManager->addErrorMessage($e->getMessage());
                }
            }
            if ($i > 0) {
                $this->messageManager->addSuccessMessage(
                    __('A total of %1 item(s) were inactivated.', $i)
                );
            }
        }
        else
        {
            $this->messageManager->addErrorMessage(
                __('You can not inactive item(s), Please check again %1')
            );
        }
        $this->_redirect('*/*/index');
    }
}

Result:

In this example, I want inactive rows 1 and 4 at the same time.

how-to-add-mass-action-in-admin-grid

Done, mass actions are super easy to make and really helpful.