Refresh page data from resource form action

I need to call refreshFormData (https://filamentphp.com/docs/3.x/panels/pages#refreshing-form-data) from an action within a resource form, but that method is on the page. How can I access the page component from the action method?
Solution:
I managed to get this fully working with: ```php ->action(function (array $data, Forms\Components\Repeater $component) { Chapter::create($data, ...); $component->clearCachedExistingRecords();...
Jump to solution
16 Replies
LeandroFerreira
LeandroFerreira2mo ago
you can inject $livewire
Jack Sleight
Jack SleightOP2mo ago
Ah ha, thanks! I tried $page. Is there a list of everything that can be passed to those closures somewhere? That works, but refreshFormData doesn't seem to be doing anything. I'm trying to refresh a relationship (displayed as a repeater). Any ideas?
Jack Sleight
Jack SleightOP2mo ago
Perfect thanks
LeandroFerreira
LeandroFerreira2mo ago
could you share the code please?
Jack Sleight
Jack SleightOP2mo ago
Sure. Just for context, I want to override the repeaters add action to use a modal that prompts for data and then actually creates the record. It all works perfectly, except I need the repeater to update with the newly added item.
Forms\Components\Repeater::make('chapters')
->relationship()
->label('Lessons')
->itemLabel(fn (array $state): ?string => $state['title'] ?? null)
->addActionAlignment(Alignment::Start)
->addAction(fn ($action) => $action
->form([
Forms\Components\TextInput::make('title')
->required(),
])
->action(function (Page $livewire, Course $record, array $data) {
Chapter::create([
...$data,
'course_id' => $record->id,
]);
$livewire->refreshFormData(['chapters']);
}))
Forms\Components\Repeater::make('chapters')
->relationship()
->label('Lessons')
->itemLabel(fn (array $state): ?string => $state['title'] ?? null)
->addActionAlignment(Alignment::Start)
->addAction(fn ($action) => $action
->form([
Forms\Components\TextInput::make('title')
->required(),
])
->action(function (Page $livewire, Course $record, array $data) {
Chapter::create([
...$data,
'course_id' => $record->id,
]);
$livewire->refreshFormData(['chapters']);
}))
LeandroFerreira
LeandroFerreira2mo ago
try this please
Forms\Components\Repeater::make('chapters')
...
->registerListeners([
'refreshChapters' => [
function (Repeater $component, Course $record) {
$component->state($record->chapters->toArray());
},
],
])
Forms\Components\Repeater::make('chapters')
...
->registerListeners([
'refreshChapters' => [
function (Repeater $component, Course $record) {
$component->state($record->chapters->toArray());
},
],
])
Chapter::create([...]);
$livewire->dispatchFormEvent('refreshChapters', record: $record);
Chapter::create([...]);
$livewire->dispatchFormEvent('refreshChapters', record: $record);
Jack Sleight
Jack SleightOP2mo ago
That works, thanks! But, when you then hit save on the form it attempts to save the chapter again, which fails with a null title column error, and that somehow deletes the row that was previously added... do I need to tell it that item already exists somehow?
LeandroFerreira
LeandroFerreira2mo ago
hum not sure. I think the correct approach would be to create/update the relationship items using the default submit page action
Jack Sleight
Jack SleightOP2mo ago
Yeah I did try that, but I need the drag and drop re-ordering feature. May have to cook up a custom field.
LeandroFerreira
LeandroFerreira2mo ago
There is a reorderable function in Filament tables that you can use. Yes, you can also create a custom field and manage it as you need.
Jack Sleight
Jack SleightOP2mo ago
Ah OK, thanks I'll check that out. It does get even more complicated, because each chapter then has a list of lessons, and ideally I want to end up with a single view where you can add/edit/delete/reorder chapters and lessons 😂 In theory repeater works great for this, I've got the add/edit/delete/reorder working great, it's just syncing the data after the actions that's the issue.
Solution
Jack Sleight
Jack Sleight2mo ago
I managed to get this fully working with:
->action(function (array $data, Forms\Components\Repeater $component) {
Chapter::create($data, ...);
$component->clearCachedExistingRecords();
$component->fillFromRelationship();
})
->action(function (array $data, Forms\Components\Repeater $component) {
Chapter::create($data, ...);
$component->clearCachedExistingRecords();
$component->fillFromRelationship();
})
Thanks again for your help!
LeandroFerreira
LeandroFerreira2mo ago
much better 👌
Jack Sleight
Jack SleightOP2mo ago
And it works perfectly on the nested repeaters as well.

Did you find this page helpful?