Hello Everyone,
I have successfully added a custom button to the list view for bulk actions. However, I am facing an issue with triggering my custom modal upon clicking the button. Could anyone provide guidance or suggestions on how to implement this functionality?
@rsp thanks for sharing the video. For learning purpose, I have added a simple bulk action in the Accounts module. Sharing here the steps here as it might help others.
Add app strings for Action Label and Success Message
file path: \public\legacy\custom\include\language\en_us.lang.php (create this file if doesn’t exist)
<?php
$app_strings['LBL_SEND_BULK_SMS']='Send Bulk SMS Message';
$app_strings['LBL_SEND_BULK_SMS_SUCCESS']='Sent SMS messages to these accounts successfully!';
Add bulk action definition with a key ‘send-bulk-sms-list’ in listviewdefs for the required module in custom folder
file path: custom/modules/Accounts/metadata/listviewdefs.php
'bulkActions' => [
'actions' => [
...
...
'send-bulk-sms-list' => [
'key' => 'send-bulk-sms-list',
'labelKey' => 'LBL_SEND_BULK_SMS',
'modes' => ['list'],
'params' => [
'allowAll' => false,
'max' => 200
]
],
Add bulk action logic by creating a file in \core\backend\Process\Service\BulkActions directory
The PROCESS_TYPE is prefixed with ‘bulk-’
file path: \core\backend\Process\Service\BulkActions\SendSMSBulkAction.php
(referred \core\backend\Process\Service\BulkActions\DeleteRecordsBulkAction.php)
<?php
namespace App\Process\Service\BulkActions;
use ApiPlatform\Exception\InvalidArgumentException;
use App\Data\Service\RecordDeletionServiceInterface;
use App\Module\Service\ModuleNameMapperInterface;
use App\Process\Entity\Process;
use App\Process\Service\ProcessHandlerInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
class SendSMSBulkAction implements ProcessHandlerInterface, LoggerAwareInterface
{
protected const MSG_OPTIONS_NOT_FOUND = 'Process options is not defined';
protected const PROCESS_TYPE = 'bulk-send-bulk-sms-list';
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var ModuleNameMapperInterface
*/
private $moduleNameMapper;
/**
* @var RecordDeletionServiceInterface
*/
private $recordDeletionProvider;
public function __construct(
ModuleNameMapperInterface $moduleNameMapper
) {
$this->moduleNameMapper = $moduleNameMapper;
}
/**
* @inheritDoc
*/
public function getProcessType(): string
{
return self::PROCESS_TYPE;
}
/**
* @inheritDoc
*/
public function requiredAuthRole(): string
{
return 'ROLE_USER';
}
/**
* @inheritDoc
*/
public function getRequiredACLs(Process $process): array
{
$options = $process->getOptions();
$module = $options['module'] ?? '';
$ids = $options['ids'] ?? [];
return [
$module => [
[
'action' => 'list',
'ids' => $ids
]
]
];
}
/**
* @inheritDoc
*/
public function configure(Process $process): void
{
//This process is synchronous
//We aren't going to store a record on db
//thus we will use process type as the id
$process->setId(self::PROCESS_TYPE);
$process->setAsync(false);
}
/**
* @inheritDoc
*/
public function validate(Process $process): void
{
if (empty($process->getOptions())) {
throw new InvalidArgumentException(self::MSG_OPTIONS_NOT_FOUND);
}
$options = $process->getOptions();
if (empty($options['module']) || empty($options['action'])) {
throw new InvalidArgumentException(self::MSG_OPTIONS_NOT_FOUND);
}
}
/**
* @inheritDoc
*/
public function run(Process $process)
{
$result = $this->sendSMSToRecords($process);
$responseData = [
'reload' => false,
];
if($result>0){
$process->setStatus('success');
$process->setMessages(['LBL_SEND_BULK_SMS_SUCCESS']);
}
else {
$process->setStatus('error');
$process->setMessages(['LBL_ACTION_ERROR']);
}
$process->setData($responseData);
}
/**
* @param Process $process
* @return bool
*/
protected function sendSMSToRecords(Process $process): int
{
$options = $process->getOptions();
if (is_array($options['ids']) && count($options['ids'])) {
$module = $this->moduleNameMapper->toLegacy($options['module']);
$ids = $options['ids'];
//send sms logic
return count($ids);
}
return 0;
}
/**
* @inheritDoc
*/
public function setLogger(LoggerInterface $logger): void
{
$this->logger = $logger;
}
}
This is very simple example. We can improve this solution if required or any issue in the code. Thanks
3 Likes
Hello Harshad,
Thanks for sharing the details
but when I follow the same steps I face the below issue.
Also how do I open the model on click of the bulk.
I think the following can help get rid of this error
Delete {Root}/cache/prod
Please do quick repair & rebuild
Clear browser cache as well.
Thanks!
Thanks for the help its working now.
Can you guide me to open the new model when I click on bulk.
Please refer to the oob ‘Add Records To Target List’ from the Accounts module
public/legacy/modules/Accounts/metadata/listviewdefs.php
actions' => [
'records-to-target-list' => [
'key' => 'records-to-target-list',
'labelKey' => 'LBL_ADD_TO_PROSPECT_LIST_BUTTON_LABEL',
'modes' => ['list'],
'acl' => ['edit'],
'aclModule' => 'prospect-lists',
'params' => [
'selectModal' => [
'module' => 'ProspectLists'
],
'allowAll' => false,
'max' => 200
]
],
core/backend/Process/LegacyHandler/AddRecordsToTargetListBulkActionHandler.php
Also please mark above code as solution as it might help all. Thanks!
1 Like
pgr
16 October 2024 10:53
9
(@Harshad please see my edit to your post to learn how to use code blocks in these forums, you will find it is very helpful to keep formatting and do syntax highlighting )
1 Like