$getAction() with arguments

Is it possible to render a Infolists\Components\Actions\Action registered on a Infolists\Components\Entry via $this->registerActions(), passing arguments from the view? I have:
class TranslationsInfo extends \Filament\Infolists\Components\Entry
{
protected string $view = 'infolists.components.translations-info';
protected function setUp(): void
{
parent::setUp();
$this->registerActions([
Action::make('myAction')
->action(function (array $arguments) {
dump($arguments['language']);
})
]);
}
}
class TranslationsInfo extends \Filament\Infolists\Components\Entry
{
protected string $view = 'infolists.components.translations-info';
protected function setUp(): void
{
parent::setUp();
$this->registerActions([
Action::make('myAction')
->action(function (array $arguments) {
dump($arguments['language']);
})
]);
}
}
I have tried with no result:
{{ $getAction('myAction', ['language' => 'es']) }}
{{ $getAction('myAction')->arguments(['language' => 'es']) }}
{{ $getAction('myAction')(['language' => 'es']) }}
{{ ($this->myAction)(['language' => 'es']) }}
{{ $getAction('myAction', ['language' => 'es']) }}
{{ $getAction('myAction')->arguments(['language' => 'es']) }}
{{ $getAction('myAction')(['language' => 'es']) }}
{{ ($this->myAction)(['language' => 'es']) }}
24 Replies
damarev
damarev4w ago
Thank you Leandro. Yes I have tried this also:
public function myAction()
{
Action::make('myAction')
->action(function (array $arguments) {
dd($arguments);
});
}
public function myAction()
{
Action::make('myAction')
->action(function (array $arguments) {
dd($arguments);
});
}
and in the view
{{ ($this->myAction)(['language' => 'es']) }}
{{ ($this->myAction)(['language' => 'es']) }}
But it throws an exception: Livewire\Exceptions\PropertyNotFoundException - Property not found on component.
Adapt.Patrick
Adapt.Patrick4w ago
I'm experiencing something similar here, @damarev & @LeandroFerreira. Any chance you've made any progress? My setup looks like this from the infolist() method of a resource:
public static function infolist(Infolist $infolist): Infolist
{
return $infolist->schema([
Group::make()
->schema([
self::infolistQuoteRooms(),
])
->columnSpan(1),
// ...
]);
}

private static function infolistQuoteRooms(): InfoSection
{
return InfoSection::make('Rooms')
->schema([
RepeatableEntry::make('rooms')
->hiddenLabel()
->schema([
ViewEntry::make('quoteRoom')
->view('filament.infolists.entries.quote-room')
->hiddenLabel()
->registerActions([
self::editRoomAction()
])
])
->contained(false),
])
// ...
}

public static function editRoomAction(): Action
{
// ...

return Action::make('editRoom')
// ...
->fillForm(function (array $arguments) {
$room = new Room($arguments);
})
// ...
public static function infolist(Infolist $infolist): Infolist
{
return $infolist->schema([
Group::make()
->schema([
self::infolistQuoteRooms(),
])
->columnSpan(1),
// ...
]);
}

private static function infolistQuoteRooms(): InfoSection
{
return InfoSection::make('Rooms')
->schema([
RepeatableEntry::make('rooms')
->hiddenLabel()
->schema([
ViewEntry::make('quoteRoom')
->view('filament.infolists.entries.quote-room')
->hiddenLabel()
->registerActions([
self::editRoomAction()
])
])
->contained(false),
])
// ...
}

public static function editRoomAction(): Action
{
// ...

return Action::make('editRoom')
// ...
->fillForm(function (array $arguments) {
$room = new Room($arguments);
})
// ...
I'm then calling the editRoomAction() in my filament.infolists.entries.quote-room template with {{ $getAction('editRoom') }} My issue is $arguments in the editRoomAction() method is empty. The call to my editRoom action from the view successfully renders a button which opens a modal, but the contents of the form is empty as the $arguments parameter of the fillForm() callback is an empty array. 😓
LeandroFerreira
Why not an action in the repeater?
Actions::make([
Actions\Action::make('editRoom')
->form([
//...
])
])
Actions::make([
Actions\Action::make('editRoom')
->form([
//...
])
])
Adapt.Patrick
Adapt.Patrick3w ago
Thanks for getting back to me @Leandro Ferreira. Will that still allow us to use a custom view file for the rendering of each item in the repeater?
LeandroFerreira
maybe you could try this way to achieve what you need
Adapt.Patrick
Adapt.Patrick3w ago
Forgive me, but I'm not sure I'm following where this Actions::make() call is supposed to live? Is it part of the RepeatableEntry::make() call?
LeandroFerreira
RepeatableEntry::make('rooms')
->schema([
\Filament\Infolists\Components\Actions::make([
\Filament\Infolists\Components\Actions\Action::make('editRoom')
->form([
//...
]),
]),
])
RepeatableEntry::make('rooms')
->schema([
\Filament\Infolists\Components\Actions::make([
\Filament\Infolists\Components\Actions\Action::make('editRoom')
->form([
//...
]),
]),
])
Adapt.Patrick
Adapt.Patrick3w ago
Thank you! Does this not remove the ability for use to use a custom view(), though?
LeandroFerreira
no, you can combine
Adapt.Patrick
Adapt.Patrick3w ago
That doesn't appear to be receiving any data to the form either, I'm afraid. The $arguments parameter is still coming through as an empty array ([])
LeandroFerreira
could you share the code?
Adapt.Patrick
Adapt.Patrick3w ago
Sure! 2 secs...
Section::make('Rooms')
->schema([
RepeatableEntry::make('rooms')
->hiddenLabel()
->schema([
\Filament\Infolists\Components\Actions::make([
\Filament\Infolists\Components\Actions\Action::make('editRoom')
->fillForm()
->form(self::getFormRoom()),
]),
// ...
])
]);
Section::make('Rooms')
->schema([
RepeatableEntry::make('rooms')
->hiddenLabel()
->schema([
\Filament\Infolists\Components\Actions::make([
\Filament\Infolists\Components\Actions\Action::make('editRoom')
->fillForm()
->form(self::getFormRoom()),
]),
// ...
])
]);
Adapt.Patrick
Adapt.Patrick3w ago
This produces this in the UI. Clicking the Edit Room button opens a modal, but it's empty.
No description
No description
LeandroFerreira
hum.. you want to pass the repeater data to the form.. 🤔
Adapt.Patrick
Adapt.Patrick3w ago
I should say, self::getFormRoom() is just a wrapper to return the array of form fields (just to help keep the code tidy). So it should use the same context as if I were to declare them directly in the ->form() call. 🙂
LeandroFerreira
yes, and you want to fill the edit form with the repeater data, right? Is rooms a relationship?
Adapt.Patrick
Adapt.Patrick3w ago
Correct & yes, rooms is a relationship on the resource's model. It loads related entries perfectly.
LeandroFerreira
you want to create a Repeater in a Infolist 😅
Adapt.Patrick
Adapt.Patrick3w ago
Correct - that's what I've got... 😬😅
LeandroFerreira
now I know why you are registering an action.. let me think about it..
Adapt.Patrick
Adapt.Patrick3w ago
Thank you so much. 🙇‍♂️ As far as I know, I'm doing everything "by the book" per the documentation but I could be missing something crucial.
LeandroFerreira
maybe we have a better way, but I think you could try this: Add this action to your ViewPage
public function editRoomAction(): Actions\Action
{
return Actions\Action::make('editRoom')
->fillForm(fn (array $arguments) => $arguments['room']['record'])
->form([
//...
])
->action(function (array $arguments, array $data) {
//...
});
}
public function editRoomAction(): Actions\Action
{
return Actions\Action::make('editRoom')
->fillForm(fn (array $arguments) => $arguments['room']['record'])
->form([
//...
])
->action(function (array $arguments, array $data) {
//...
});
}
Create a custom-repeater-entry.blade.php in your resources/view folder and copy the default content from repeater-entry.blade.php. Add the action:
@foreach ($childComponentContainers as $container)
<li>
...
{{ ($this->editRoomAction)(['room' => $container]) }}
</li>
@endforeach
@foreach ($childComponentContainers as $container)
<li>
...
{{ ($this->editRoomAction)(['room' => $container]) }}
</li>
@endforeach
Use this view in the Repeater:
RepeatableEntry::make('rooms')
->view('custom-repeater-entry')
RepeatableEntry::make('rooms')
->view('custom-repeater-entry')
Adapt.Patrick
Adapt.Patrick3w ago
Interesting! As you say, it feels a little "hacky" but I'll give it a go, for sure! 🙌 Hmm, I think we might be getting somewhere with this now. I'd be keen to keep this thread open though, as you've already said, I feel there should be a more elegant solution to this... 🤔