Magento 2 Development 15: MassAction

0

 

The MassAction allows us to perform an operation on multiple items of the grid. You may have seen mass actions on the product grid, which allows us to delete multiple product at once.

In this blog we will create some mass actions. First we will create a MassAction to delete multiple blogs at once. We need to edit the ui component file view/adminhtml/ui_component/blogmanager_blog_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">blogmanager_blog_listing.blogmanager_blog_listing_data_source</item>
<item name="deps" xsi:type="string">blogmanager_blog_listing.blogmanager_blog_listing_data_source</item>
</item>
<item name="spinner" xsi:type="string">blogmanager_blog_columns</item>
</argument>
<dataSource name="blogmanager_blog_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument>
<argument name="name" xsi:type="string">blogmanager_blog_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_id</argument>
<argument name="requestFieldName" xsi:type="string">entity_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="update_url" xsi:type="url" path="mui/index/render"/>
<item name="storageConfig" xsi:type="array">
<item name="indexField" xsi:type="string">entity_id</item>
</item>
</item>
</argument>
</argument>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
</item>
</argument>
</dataSource>
<listingToolbar name="listing_top">
<massaction name="listing_massaction">
<argument name="data" xsi:type="array">
<item name="data" xsi:type="array">
<item name="selectProvider" xsi:type="string">blogmanager_blog_listing.blogmanager_blog_listing.blogmanager_blog_columns.ids</item>
<item name="displayArea" xsi:type="string">bottom</item>
<item name="indexField" xsi:type="string">entity_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="blog/manage/massDelete"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Delete Blogs?</item>
<item name="message" xsi:type="string" translate="true">Are you sure you want to delete the selected blogs?</item>
</item>
</item>
</argument>
</action>
</massaction>
<bookmark name="bookmarks"/>
<columnsControls name="columns_controls"/>
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<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>
</argument>
</filters>
<paging name="listing_paging"/>
</listingToolbar>
<columns name="blogmanager_blog_columns">
<selectionsColumn name="ids">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="indexField" xsi:type="string">entity_id</item>
</item>
</argument>
</selectionsColumn>
<column name="entity_id">
<settings>
<filter>textRange</filter>
<label translate="true">ID</label>
<resizeDefaultWidth>25</resizeDefaultWidth>
</settings>
</column>
<column name="user_name">
<settings>
<filter>text</filter>
<label translate="true">User</label>
</settings>
</column>
<column name="title">
<settings>
<filter>text</filter>
<label translate="true">Title</label>
</settings>
</column>
<column name="content" class="Webkul\BlogManager\Ui\Component\Listing\Columns\Content">
<settings>
<filter>false</filter>
<sortable>false</sortable>
<label translate="true">Content</label>
</settings>
</column>
<column name="status" component="Magento_Ui/js/grid/columns/select">
<settings>
<options class="Webkul\BlogManager\Model\Blog\Status"/>
<dataType>select</dataType>
<filter>select</filter>
<sortable>false</sortable>
<label translate="true">Status</label>
</settings>
</column>
<column name="updated_at" component="Magento_Ui/js/grid/columns/date">
<settings>
<filter>dateRange</filter>
<dataType>date</dataType>
<label translate="true">Updated</label>
</settings>
</column>
<column name="created_at" component="Magento_Ui/js/grid/columns/date">
<settings>
<filter>dateRange</filter>
<dataType>date</dataType>
<label translate="true">Created</label>
</settings>
</column>
</columns>
</listing>

Here we have added selectionsColumn tag inside the columns tag. It will show the checkbox column to select the rows.

And inside the listingToolbar tag we have added massaction tag which will be used to manage the mass-action dropdown. To add the mass-action action, we have used the action tag, where we have specified label, url for the mass-action, confirmation message, etc.

Now let’s create the action file for the mass-delete url, Controller/Adminhtml/Manage/MassDelete.php

<?php
namespace Webkul\BlogManager\Controller\Adminhtml\Manage;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Ui\Component\MassAction\Filter;
use Webkul\BlogManager\Model\ResourceModel\Blog\CollectionFactory;
class MassDelete extends Action
{
public $collectionFactory;
public $filter;
public function __construct(
Context $context,
Filter $filter,
CollectionFactory $collectionFactory
) {
$this->filter = $filter;
$this->collectionFactory = $collectionFactory;
parent::__construct($context);
}
public function execute()
{
try {
$collection = $this->filter->getCollection($this->collectionFactory->create());
$count = 0;
foreach ($collection as $model) {
$model->delete();
$count++;
}
$this->messageManager->addSuccess(__('A total of %1 blog(s) have been deleted.', $count));
} catch (\Exception $e) {
$this->messageManager->addError(__($e->getMessage()));
}
return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('*/*/index');
}
public function _isAllowed()
{
return $this->_authorization->isAllowed('Webkul_BlogManager::delete');
}
}

Let’s see what’s this line is doing,
$this->filter->getCollection($this->collectionFactory->create());
With $this->collectionFactory->create(), we are getting the whole blogs collection. And we are passing it in getCollection method of mass-action’s filter class. So it will return the collection of all the rows which we selected while performing this action. And we are iterating through each model and deleting them one by one.

There are few other things new here, which are not limited to mass-action.
__(‘A total of %1 blog(s) have been deleted.’, $count) – the %1 will get replaced with $count
Similarly we can pass multiple variables and format string.

->setPath(‘*/*/index’) – here * means replace this component with current value. So it will replace frontName and controllerName with current values which will be blog and manage respectively.

Please ignore _isAllowed method we will discuss about it when we create ACL as mentioned earlier.

Now you should get similar result as below,

ezgif.com-gif-maker-2

PS: The selection column might come at the end as last column. That’s because bookmark has been saved in magento . So we can delete that bookmark by running
delete from ui_bookmark where namespace=”blogmanager_blog_listing”;
sql query.



MassActions Tree

Now let’s another mass-action to allow the admin to change the status of the blogs. Once again we have to edit the ui component file view/adminhtml/ui_component/blogmanager_blog_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">blogmanager_blog_listing.blogmanager_blog_listing_data_source</item>
<item name="deps" xsi:type="string">blogmanager_blog_listing.blogmanager_blog_listing_data_source</item>
</item>
<item name="spinner" xsi:type="string">blogmanager_blog_columns</item>
</argument>
<dataSource name="blogmanager_blog_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument>
<argument name="name" xsi:type="string">blogmanager_blog_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_id</argument>
<argument name="requestFieldName" xsi:type="string">entity_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="update_url" xsi:type="url" path="mui/index/render"/>
<item name="storageConfig" xsi:type="array">
<item name="indexField" xsi:type="string">entity_id</item>
</item>
</item>
</argument>
</argument>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
</item>
</argument>
</dataSource>
<listingToolbar name="listing_top">
<massaction name="listing_massaction" component="Magento_Ui/js/grid/tree-massactions">
<argument name="data" xsi:type="array">
<item name="data" xsi:type="array">
<item name="selectProvider" xsi:type="string">blogmanager_blog_listing.blogmanager_blog_listing.blogmanager_blog_columns.ids</item>
<item name="displayArea" xsi:type="string">bottom</item>
<item name="indexField" xsi:type="string">entity_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="blog/manage/massDelete"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Delete Blogs?</item>
<item name="message" xsi:type="string" translate="true">Are you sure you want to delete the selected blogs?</item>
</item>
</item>
</argument>
</action>
<action name="status">
<settings>
<type>status</type>
<label translate="true">Change status</label>
<actions>
<action name="0">
<type>enable</type>
<label translate="true">Enable</label>
<url path="blog/manage/massStatus">
<param name="status">1</param>
</url>
</action>
<action name="1">
<type>disable</type>
<label translate="true">Disable</label>
<url path="blog/manage/massStatus">
<param name="status">0</param>
</url>
</action>
</actions>
</settings>
</action>
</massaction>
<bookmark name="bookmarks"/>
<columnsControls name="columns_controls"/>
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<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>
</argument>
</filters>
<paging name="listing_paging"/>
</listingToolbar>
<columns name="blogmanager_blog_columns">
<selectionsColumn name="ids">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="indexField" xsi:type="string">entity_id</item>
</item>
</argument>
</selectionsColumn>
<column name="entity_id">
<settings>
<filter>textRange</filter>
<label translate="true">ID</label>
<resizeDefaultWidth>25</resizeDefaultWidth>
</settings>
</column>
<column name="user_name">
<settings>
<filter>text</filter>
<label translate="true">User</label>
</settings>
</column>
<column name="title">
<settings>
<filter>text</filter>
<label translate="true">Title</label>
</settings>
</column>
<column name="content" class="Webkul\BlogManager\Ui\Component\Listing\Columns\Content">
<settings>
<filter>false</filter>
<sortable>false</sortable>
<label translate="true">Content</label>
</settings>
</column>
<column name="status" component="Magento_Ui/js/grid/columns/select">
<settings>
<options class="Webkul\BlogManager\Model\Blog\Status"/>
<dataType>select</dataType>
<filter>select</filter>
<sortable>false</sortable>
<label translate="true">Status</label>
</settings>
</column>
<column name="updated_at" component="Magento_Ui/js/grid/columns/date">
<settings>
<filter>dateRange</filter>
<dataType>date</dataType>
<label translate="true">Updated</label>
</settings>
</column>
<column name="created_at" component="Magento_Ui/js/grid/columns/date">
<settings>
<filter>dateRange</filter>
<dataType>date</dataType>
<label translate="true">Created</label>
</settings>
</column>
</columns>
</listing>

We have added one more action tag in the massaction tag. And in that action tag we have added two sub-actions whose URLs are same but we have passed status param with different values.

Since it has sub-action structure, so we need to add the component attribute in massaction tag to use tree-massactions component.

Now let’s create the action file as Controller/Adminhtml/Manage/MassStatus.php

<?php
namespace Webkul\BlogManager\Controller\Adminhtml\Manage;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Ui\Component\MassAction\Filter;
use Webkul\BlogManager\Model\ResourceModel\Blog\CollectionFactory;
class MassStatus extends Action
{
public $collectionFactory;
public $filter;
public function __construct(
Context $context,
Filter $filter,
CollectionFactory $collectionFactory
) {
$this->filter = $filter;
$this->collectionFactory = $collectionFactory;
parent::__construct($context);
}
public function execute()
{
try {
$collection = $this->filter->getCollection($this->collectionFactory->create());
$status = $this->getRequest()->getParam('status');
$statusLabel = $status ? "enabled" : "disabled";
$count = 0;
foreach ($collection as $model) {
$model->setStatus($status);
$model->save();
$count++;
}
$this->messageManager->addSuccess(__('A total of %1 blog(s) have been %2.', $count, $statusLabel));
} catch (\Exception $e) {
$this->messageManager->addError(__($e->getMessage()));
}
return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('*/*/index');
}
public function _isAllowed()
{
return $this->_authorization->isAllowed('Webkul_BlogManager::edit');
}
}

Here we are doing similar things as we did earlier. We are iterating through each selected blogs and setting the status as the value passed in the param. We set this param-value in the ui component.

Now you will see the change status mass-action as below,

2021-03-05_17-47


Folder Structure,

2021-03-05_18-02



Post a Comment

0Comments
Post a Comment (0)
To Top