F
Filamentā€¢8mo ago
Hugo

Navigate between records on ViewAction

Hi, Following the doc, I'm trying to perform an action in the extraModalFooterActions, I'd like to reset the form and not close the modal as indicated in the doc as a comment. Can anyone explain how to do this ? (// Reset the form and don't close the modal) Thanks !
No description
20 Replies
toeknee
toekneeā€¢8mo ago
$this->form->reset() ? or $this->reset? or $this->form->fill([])
Hugo
HugoOPā€¢8mo ago
i can't use $this in ->action() Using $this when not in object context Here my code :
Tables\Actions\ViewAction::make()
->name('carousel')
->modalWidth('full')
->stickyModalHeader()
->stickyModalFooter()
->hiddenLabel()
->icon(null)
->modalHeading(fn(Application $record) => __('filament-actions::view.single.modal.heading', ['label' => $record->applicant->firstname . ' ' . $record->applicant->lastname]))
->modalCancelAction(false)
->modalFooterActionsAlignment(Alignment::Center)
->extraModalFooterActions(fn (Tables\Actions\Action $action): array => [
$action->makeModalSubmitAction('nextRecord', arguments: ['type' => 'next']),
$action->makeModalSubmitAction('prevRecord', arguments: ['type' => 'prev']),
])
->action(function (array $data, array $arguments, Tables\Actions\ViewAction $action, Table $table, $record, Form $form): void {

if ($arguments['type'] == 'next') {

$action->callAfter();

$records = $table->getRecords();
$index = array_search($record, $records->items());
$next = $records[$index + 1] ?? $records[0];

$action->record($next);

$form->fill($next->attributesToArray());

$action->halt();

return;
}

}),
Tables\Actions\ViewAction::make()
->name('carousel')
->modalWidth('full')
->stickyModalHeader()
->stickyModalFooter()
->hiddenLabel()
->icon(null)
->modalHeading(fn(Application $record) => __('filament-actions::view.single.modal.heading', ['label' => $record->applicant->firstname . ' ' . $record->applicant->lastname]))
->modalCancelAction(false)
->modalFooterActionsAlignment(Alignment::Center)
->extraModalFooterActions(fn (Tables\Actions\Action $action): array => [
$action->makeModalSubmitAction('nextRecord', arguments: ['type' => 'next']),
$action->makeModalSubmitAction('prevRecord', arguments: ['type' => 'prev']),
])
->action(function (array $data, array $arguments, Tables\Actions\ViewAction $action, Table $table, $record, Form $form): void {

if ($arguments['type'] == 'next') {

$action->callAfter();

$records = $table->getRecords();
$index = array_search($record, $records->items());
$next = $records[$index + 1] ?? $records[0];

$action->record($next);

$form->fill($next->attributesToArray());

$action->halt();

return;
}

}),
I have no errors, but the form fields do not update with the new record.
toeknee
toekneeā€¢8mo ago
I am unsure what you are trying to do, are you trying to change the loaded record within the model?
Hugo
HugoOPā€¢8mo ago
I would like to make prev and next buttons that allow me to navigate between model records in the modal Now the next button works, but the form loses the record and I don't know how to set the new record :
->action(function (array $data, array $arguments, Tables\Actions\ViewAction $action, Table $table, $record, Form $form): void {

if ($arguments['type'] == 'next') {

$records = $table->getRecords();
$index = array_search($record, $records->items());
$next = $records[$index + 1] ?? $records[0];

$action->record($next);
$action->model(Application::class);

$form->model(Application::class);
$form->operation('view');

$form->fill($next->attributesToArray());

$action->halt();

return;
}

}),
->action(function (array $data, array $arguments, Tables\Actions\ViewAction $action, Table $table, $record, Form $form): void {

if ($arguments['type'] == 'next') {

$records = $table->getRecords();
$index = array_search($record, $records->items());
$next = $records[$index + 1] ?? $records[0];

$action->record($next);
$action->model(Application::class);

$form->model(Application::class);
$form->operation('view');

$form->fill($next->attributesToArray());

$action->halt();

return;
}

}),
Hugo
HugoOPā€¢8mo ago
First screen : click on table row => open modal Second screen : click on "Next record" button The next record isn't set on the form...
No description
No description
toeknee
toekneeā€¢8mo ago
Usually you would use mountUsing or pass in the record like you have. If you adjust the action to use mountUsing, you might be able to use $form->fill()? Since the model will be detacted. You'll likely need to build the save method into ->action() then though.
LeandroFerreira
LeandroFerreiraā€¢8mo ago
GitHub
infolist-example/screenshots/example-1.gif at page-actions Ā· filame...
Filament infolist example. Contribute to filament-br/infolist-example development by creating an account on GitHub.
Hugo
HugoOPā€¢8mo ago
I see, I'll try to adapt it to my ViewAction, thanks !
LeandroFerreira
LeandroFerreiraā€¢8mo ago
GitHub
infolist-example/app/Filament/Resources/Actions at page-actions Ā· f...
Filament infolist example. Contribute to filament-br/infolist-example development by creating an account on GitHub.
GitHub
infolist-example/app/Filament/Resources/Pages/Concerns/CanPaginateV...
Filament infolist example. Contribute to filament-br/infolist-example development by creating an account on GitHub.
Hugo
HugoOPā€¢8mo ago
Nice, I'd seen šŸ˜‰
LeandroFerreira
LeandroFerreiraā€¢8mo ago
You can clone this repo and use this branch page-actions if you want. This is working Check the ViewPost page šŸ‘
No description
Hugo
HugoOPā€¢8mo ago
But as I don't use pages, but a modal, I have to change the record to next or previous, so how to do instead of $action->url(fn (): string => static::getResource()::getUrl(static::getResourcePageName(), ['record' => $this->getNextRecord() ])); in your trait ? šŸ˜•
LeandroFerreira
LeandroFerreiraā€¢8mo ago
not sure, $action->record maybe?
Hugo
HugoOPā€¢8mo ago
The record doesn't change with the next or the prev... and I have no errors :
trait CanPaginateViewRecord
{
public function prepareModalAction(StaticAction $action): StaticAction
{
$action = match (true) {
$action instanceof PreviousAction => $this->configurePreviousAction($action),
$action instanceof NextAction => $this->configureNextAction($action),

default => null,
};

return parent::prepareModalAction($action);
}

protected function configurePreviousAction(Action $action): Action
{
if ($this->getPreviousRecord()) {
$action->action(function () {
$this->record($this->getPreviousRecord());
$this->model(Application::class);
});
} else {
$action
->disabled()
->color('gray');
}

return $action;
}

protected function configureNextAction(Action $action): Action
{
if ($this->getNextRecord()) {
$action->action(function () {
$this->record($this->getNextRecord());
$this->model(Application::class);
});
} else {
$action
->disabled()
->color('gray');
}

return $action;
}
...
trait CanPaginateViewRecord
{
public function prepareModalAction(StaticAction $action): StaticAction
{
$action = match (true) {
$action instanceof PreviousAction => $this->configurePreviousAction($action),
$action instanceof NextAction => $this->configureNextAction($action),

default => null,
};

return parent::prepareModalAction($action);
}

protected function configurePreviousAction(Action $action): Action
{
if ($this->getPreviousRecord()) {
$action->action(function () {
$this->record($this->getPreviousRecord());
$this->model(Application::class);
});
} else {
$action
->disabled()
->color('gray');
}

return $action;
}

protected function configureNextAction(Action $action): Action
{
if ($this->getNextRecord()) {
$action->action(function () {
$this->record($this->getNextRecord());
$this->model(Application::class);
});
} else {
$action
->disabled()
->color('gray');
}

return $action;
}
...
class PaginatedAction extends ViewAction
{
use CanPaginateViewRecord;

protected function setUp(): void
{
parent::setUp();

$this->extraModalFooterActions([
PreviousAction::make(),
NextAction::make(),
]);
}
}
class PaginatedAction extends ViewAction
{
use CanPaginateViewRecord;

protected function setUp(): void
{
parent::setUp();

$this->extraModalFooterActions([
PreviousAction::make(),
NextAction::make(),
]);
}
}
When you click on prev or next, the new record is applied to the action, but the fields in the form are not updated I've also tried using ->fillForm(), but it doesn't work either
toeknee
toekneeā€¢8mo ago
I'm not sure you can do this once it has loaded tbh
LeandroFerreira
LeandroFerreiraā€¢8mo ago
are you using a resource simple, right?
Hugo
HugoOPā€¢8mo ago
Yes i call my Action like that :
PaginatedAction::make('paginated')
->form(ApplicationResource::getResourceForm())
->stickyModalHeader()
->stickyModalFooter()
->modalCancelAction(false)
->modalFooterActionsAlignment(Alignment::Center)
->modalWidth('full'),
PaginatedAction::make('paginated')
->form(ApplicationResource::getResourceForm())
->stickyModalHeader()
->stickyModalFooter()
->modalCancelAction(false)
->modalFooterActionsAlignment(Alignment::Center)
->modalWidth('full'),
LeandroFerreira
LeandroFerreiraā€¢8mo ago
ok, try to inject your ManagePage and use mountedTableActionsData Just to try it...
$action->action(function (Pages\ManageXXX $livewire) {
$this->record($this->getNextRecord());
$this->model(Application::class);
$livewire->mountedTableActionsData[0] = $this->getNextRecord()->attributesToArray();
});
$action->action(function (Pages\ManageXXX $livewire) {
$this->record($this->getNextRecord());
$this->model(Application::class);
$livewire->mountedTableActionsData[0] = $this->getNextRecord()->attributesToArray();
});
Hugo
HugoOPā€¢8mo ago
This pretty much works, not all of my fields are completely populated. I think it's a good lead in any case. I'll continue to dig in this direction. Thanks ! šŸ˜„
LeandroFerreira
LeandroFerreiraā€¢8mo ago
Yes. It could be better šŸ‘
Want results from more Discord servers?
Add your server