Create Dynamic Mass Action In Magento2 Grid : if you want to create dynamic mass action in any custom grid of magento2, to achieve this you have to follow some steps .
1. Write mass action code in your ui component phtml file
<massaction name="listing_massaction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="selectProvider" xsi:type="string">dynamicmassaction_massaction_listing.dynamicmassaction_massaction_listing.dynamicmassaction_massaction_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="change_status">
<settings>
<type>change_status</type>
<label translate="true">Change Status</label>
<actions class="Webkul\DynamicMassaction\Ui\Component\MassAction\Badge\Assignoptions"/>
</settings>
</action>
</massaction>
Lets take chunk of the above code for better understanding
<action name="change_status">
<settings>
<type>change_status</type>
<label translate="true">Change Status</label>
<actions class="Webkul\DynamicMassaction\Ui\Component\MassAction\Badge\Assignoptions"/>
</settings>
</action>
Here you will see a line, where you have to set the path for manipulation of the dynamic mass action
<actions class="Webkul\DynamicMassaction\Ui\Component\MassAction\Badge\Assignoptions"/>
2. Now we need to add few more lines in the etc/di.xml file as below.
<type name="Webkul\DynamicMassaction\Ui\Component\MassAction\Badge\Assignoptions">
<arguments>
<argument name="data" xsi:type="array">
<item name="urlPath" xsi:type="string">dynamicmassaction/dynamic/changestatus</item>
<item name="paramName" xsi:type="string">entity_id</item>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translatable="true">Change Status</item>
<item name="message" xsi:type="string" translatable="true">Are you sure to change the active status of selected gift card(s)?</item>
</item>
</argument>
</arguments>
</type>
3. in this path Webkul\DynamicMassaction\Ui\Component\MassAction\Badge\Assignoptions you need to manipulate your massaction
<?php
namespace Webkul\DynamicMassaction\Ui\Component\MassAction\Badge;
use Magento\Framework\UrlInterface;
use Zend\Stdlib\JsonSerializable;
use Webkul\DynamicMassaction\Model\ResourceModel\Badge\CollectionFactory;
/**
* Class Options
*/
class Assignoptions 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 UrlInterface $urlBuilder
* @param array $data
*/
public function __construct(
UrlInterface $urlBuilder,
array $data = []
) {
$this->data = $data;
$this->urlBuilder = $urlBuilder;
}
/**
* Get action options
*
* @return array
*/
public function jsonSerialize(): mixed
{
if ($this->options === null) {
// get the massaction data from the database table
//make a array of massaction
$options[0]['value']='no';
$options[0]['label']='Disable';
$options[1]['value']='yes';
$options[1]['label']='Enable';
$this->prepareData();
foreach ($options as $optionCode) {
$this->options[$optionCode['value']] = [
'type' => 'change_' . $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;
}
}
}
}
3. Now you will see your dynamically added mass actions are displaying on grid.

So in this way, you can add dynamic massaction in your grid.Hope this blog will help you.
I want another submenu for the submenu options I am getting it but there is issue. I can only get children of the first option in the menu, Second option when clicked opens the children of first option.