Magento2 Sales Grid – How to Implement Dynamic Mass Action

magento2

I trying to implement dynamic status in admin sales grid under mass action,but unable to get this.

I was able to see the single mass action but not sub mass action under the sales mass action.

I tried many blogs but it didn't work.

I have used below two blogs but it is not coming as expected

http://www.ibnab.com/en/blog/magento-2/magento-2-ui-components-new-dynamic-ui-treemassaction-technique

http://webkul.com/blog/create-dynamic-mass-action-magento-2-grid/

I have added below snippit in view/adminhtml/ui_component/sales_order_grid.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd">
  <container name="listing_top">
    <massaction name="listing_massaction">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="actions" xsi:type="array">
                    <item name="delete" xsi:type="array">
                        <item name="type" xsi:type="string">Status</item>
                        <item name="label" xsi:type="string" translate="true">Status</item>
                        <item name="url" xsi:type="string">sales/order/massStatus</item>
                    </item>
                </item>
            </item>
        </argument>
    </massaction>
</container>

Please help me to solve above problem.

enter image description here

Best Answer

To add the mass action, create the ui component and specify Magento_Ui/js/grid/tree-massactions massaction renderer

app\code\Magentoins\Pdfgenerator\view\adminhtml\ui_component\sales_order_grid.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">
    <container name="listing_top">
        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">sales_order_grid.sales_order_grid.sales_order_columns.ids</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
                    <item name="indexField" xsi:type="string">entity_id</item>
                </item>
            </argument>
            <action name="select_template">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">pdfgenerator_pdftemplates</item>
                        <item name="label" xsi:type="string" translate="true">PDF Orders</item>
                    </item>
                </argument>
                <argument name="actions" xsi:type="configurableObject">
                    <argument name="class" xsi:type="string">Magentoins\Pdfgenerator\Ui\Component\Sales\Order\MassAction\Pdftemplates</argument>
                    <argument name="data" xsi:type="array">
                        <item name="urlPath" xsi:type="string">pdfgenerator/pdfgenerator/sales_massorderpdf</item>
                        <item name="paramName" xsi:type="string">template_id</item>
                        <item name="confirm" xsi:type="array">
                            <item name="title" xsi:type="string" translate="true">PDF Template</item>
                            <item name="message" xsi:type="string" translate="true">Are you sure to use selected template for PDF?</item>
                        </item>
                    </argument>
                </argument>
            </action>
        </massaction>
    </container>
</listing>

Under the massaction class provide the action options in jsonSerialize

app\code\Magentoins\Pdfgenerator\Ui\Component\Sales\Order\MassAction\Pdftemplates.php

<?php
namespace Magentoins\Pdfgenerator\Ui\Component\Sales\Order\MassAction;
use Magento\Framework\UrlInterface;
use Zend\Stdlib\JsonSerializable;
use Magentoins\Pdfgenerator\Model\ResourceModel\Pdfgenerator\CollectionFactory;

/**
 * Class Options
 */
class Pdftemplates implements JsonSerializable
{
    /**
     * @var array
     */
    protected $options;

    /**
     * @var CollectionFactory
     */
    protected $collectionFactory;

    /**
     * Additional options params
     *
     * @var array
     */
    protected $data;

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

    /**
     * Base URL for subactions
     *
     * @var string
     */
    protected $urlPath;

    /**
     * Param name for subactions
     *
     * @var string
     */
    protected $paramName;

    /**
     * Additional params for subactions
     *
     * @var array
     */
    protected $additionalData = [];

    /**
     * Constructor
     *
     * @param CollectionFactory $collectionFactory
     * @param UrlInterface $urlBuilder
     * @param array $data
     */
    public function __construct(
        CollectionFactory $collectionFactory,
        UrlInterface $urlBuilder,
        array $data = []
    ) {
        $this->collectionFactory = $collectionFactory;
        $this->data = $data;
        $this->urlBuilder = $urlBuilder;
    }

    /**
     * Get action options
     *
     * @return array
     */
    public function jsonSerialize()
    {
        $i=0;
        if ($this->options === null) {
            // get the massaction data from the database table
            $templateCollection = $this->collectionFactory->create()->addFieldToFilter('is_active',['eq'=>1]);

            if(!count($templateCollection)){
                return $this->options;
            }
            //make a array of massaction
            foreach ($templateCollection as $key => $badge) {
                $options[$i]['value']=$badge->getEntityId();
                $options[$i]['label']=$badge->getTitle();
                $i++;
            }
            $this->prepareData();
            foreach ($options as $optionCode) {
                $this->options[$optionCode['value']] = [
                    'type' => 'template_' . $optionCode['value'],
                    'label' => $optionCode['label'],
                ];

                if ($this->urlPath && $this->paramName) {
                    $this->options[$optionCode['value']]['url'] = $this->urlBuilder->getUrl(
                        $this->urlPath,
                        [$this->paramName => $optionCode['value']]
                    );
                }

                $this->options[$optionCode['value']] = array_merge_recursive(
                    $this->options[$optionCode['value']],
                    $this->additionalData
                );
            }

            // return the massaction data
            $this->options = array_values($this->options);
        }
        return $this->options;
    }

    /**
     * Prepare addition data for subactions
     *
     * @return void
     */
    protected function prepareData()
    {

        foreach ($this->data as $key => $value) {
            switch ($key) {
                case 'urlPath':
                    $this->urlPath = $value;
                    break;
                case 'paramName':
                    $this->paramName = $value;
                    break;
                default:
                    $this->additionalData[$key] = $value;
                    break;
            }
        }
    }
}