F
Filament4mo ago
nowak

Is it possible to add validation to a `Action::make()` before opening the confirmation modal?

I have added a header action to my table, where I have tried to add validation in the ->before() lifecycle hook:
Action::make('acceptAll')
->before(function ($action, $livewire) {
Log::debug('Before hook');
$groupOrders = $livewire->getTableRecords();
foreach ($groupOrders as $groupOrder) {
if (!$groupOrder->courier) {
Notification::make()
->warning()
->title('Missing Courier')
->body('Group order with route ID ' . $groupOrder->route->id . ' does not have a courier assigned. Please assign a courier and try again.')
->persistent()
->send();
$action->cancel();
return;
}
}
})
->requiresConfirmation()
->action(function ($action, $livewire) use ($orderStatusIds){
// Action logic
}),
Action::make('acceptAll')
->before(function ($action, $livewire) {
Log::debug('Before hook');
$groupOrders = $livewire->getTableRecords();
foreach ($groupOrders as $groupOrder) {
if (!$groupOrder->courier) {
Notification::make()
->warning()
->title('Missing Courier')
->body('Group order with route ID ' . $groupOrder->route->id . ' does not have a courier assigned. Please assign a courier and try again.')
->persistent()
->send();
$action->cancel();
return;
}
}
})
->requiresConfirmation()
->action(function ($action, $livewire) use ($orderStatusIds){
// Action logic
}),
But the before hook does not trigger before the confirmation modal is opened. Am I doing something wrong? Or is there simply no lifecycle hook that triggers before the action modal is opened?
4 Replies
Jacob
Jacob4mo ago
@nowak Did you manage to get this working?
nowak
nowakOP4mo ago
@Jacob Not the way I wanted, as I don't know if a hook like this exists. So I added a conditional tooltip to my action button as well as color and icon, modal content, and submit button. This way whenever I want my action to not be validated, there is plenty of feedback to the user and they will not be able to confirm the modal if it isn't validated. Here is an example of how I conditionally show the color and icon:
Action::make('acceptAllPendingReviewing')
->label('Accept All')
->color(function (Component $livewire) {
// Change button color based on whether a record is missing a courier
return $livewire->getTableRecords()->contains(fn ($record) => !$record->courier) ? 'danger' : 'success';
})
->icon(function (Component $livewire) {
return $livewire->getTableRecords()->contains(fn ($record) => !$record->courier)
? 'heroicon-o-exclamation-circle'
: 'heroicon-m-check';
})
Action::make('acceptAllPendingReviewing')
->label('Accept All')
->color(function (Component $livewire) {
// Change button color based on whether a record is missing a courier
return $livewire->getTableRecords()->contains(fn ($record) => !$record->courier) ? 'danger' : 'success';
})
->icon(function (Component $livewire) {
return $livewire->getTableRecords()->contains(fn ($record) => !$record->courier)
? 'heroicon-o-exclamation-circle'
: 'heroicon-m-check';
})
Jacob
Jacob4mo ago
Ok thx! I managed to get it working using the ->beforeFormFilled() method, but this requires you to use an form inside the modal.
->beforeFormFilled(function (Collection $records, BulkAction $action) {
// Check for something
if (true) {
Notification::make()
->title("Can't do that!")
->danger()
->send();

$action->cancel();
}
}),
->beforeFormFilled(function (Collection $records, BulkAction $action) {
// Check for something
if (true) {
Notification::make()
->title("Can't do that!")
->danger()
->send();

$action->cancel();
}
}),
nowak
nowakOP4mo ago
@Jacob Awesome! Good to know. I do not use a form inside the modal though, but maybe I could add an empty or hidden form 🤔
Want results from more Discord servers?
Add your server