Modal with dynamic actions

I want to create a Model using a livewire or blade-view that will show a few divs. When the user clicks one of the divs, an action on the main form has to be triggered with the name of the chosen picture as an argument. What I got working is that I'm able to launch a custom Action of my Livewire modal form, but that seems to do nothing, probably because it's in the wrong place. I think the action has to be defined in my main resource somehow. But then I won't be able to access this action in the modal. Or do I, somehow?
Solution:
Ah, so you want to run something after the modal. That's not gonna work that way. You can dispatch Livewire events though and listen to those on your component. Inside your model Livewire component you probably don't even need a Filament action. Just some wire:click="$dispatch('your-event', 'data') and then you can listen for that on the page and run a method with: ```php #[On('your-event')] public function doSomething($data) {}...
Jump to solution
4 Replies
Dennis Koch
Dennis Koch3mo ago
What I got working is that I'm able to launch a custom Action of my Livewire modal form, but that seems to do nothing, probably because it's in the wrong place
It would help if you actually shared a bit of what you did.
huppeldepuppel
huppeldepuppelOP3mo ago
Yeah, I know.. Sorry about that. The thing is, I feel like I might be on the wrong track from the start, so I hesitated to share what I have so far. I might need a completely different approach, but here’s what I’ve got up to now: In my Resource headerActions() this Action:
Action::make('testform')
->action(function (array $data, array $arguments): void {
dd('action', $data, $arguments);
})
->modalContent(function (): View {
return view('filament.testform-launcher');
}),
Action::make('testform')
->action(function (array $data, array $arguments): void {
dd('action', $data, $arguments);
})
->modalContent(function (): View {
return view('filament.testform-launcher');
}),
The app\filament\testform-launcher:
<div>
@livewire('testform',['data' => $this->data])
</div>
<div>
@livewire('testform',['data' => $this->data])
</div>
The app\Livewire\Testform.php:
class Testform extends Component implements HasForms, HasActions
{
use InteractsWithForms;
use InteractsWithActions;

public ?array $data = [];

// rest of the component

public function pickItemAction(): Action
{
return Action::make('pickItemAction')
->action(function (array $arguments) {
$blockType = $arguments['blockType'];
dd($blockType);
});
}
}
class Testform extends Component implements HasForms, HasActions
{
use InteractsWithForms;
use InteractsWithActions;

public ?array $data = [];

// rest of the component

public function pickItemAction(): Action
{
return Action::make('pickItemAction')
->action(function (array $arguments) {
$blockType = $arguments['blockType'];
dd($blockType);
});
}
}
And the resources\views\livewire\testform.blade.php:
<div>
Add new block:
@foreach (['Foo','Bar'] as $blockType)
{{ $this->pickItemAction->label($blockType)(['blockType'=>$blockType]) }}
@endforeach

<x-filament-actions::modals/>
</div>
<div>
Add new block:
@foreach (['Foo','Bar'] as $blockType)
{{ $this->pickItemAction->label($blockType)(['blockType'=>$blockType]) }}
@endforeach

<x-filament-actions::modals/>
</div>
What happens now, is I'm able to click on the 2 buttons in the modal, and then the method Testform->pickItemAction() will be called, but what I want is that an Action in my Resource is being calls, since I want to change something there...
Solution
Dennis Koch
Dennis Koch3mo ago
Ah, so you want to run something after the modal. That's not gonna work that way. You can dispatch Livewire events though and listen to those on your component. Inside your model Livewire component you probably don't even need a Filament action. Just some wire:click="$dispatch('your-event', 'data') and then you can listen for that on the page and run a method with:
#[On('your-event')]
public function doSomething($data) {}
#[On('your-event')]
public function doSomething($data) {}
huppeldepuppel
huppeldepuppelOP3mo ago
Ah perfect. I ended up using ik like this:
<div wire:click="$dispatch('pickBlock', {'blockType':'{{$blockType}}'})"></div>
<div wire:click="$dispatch('pickBlock', {'blockType':'{{$blockType}}'})"></div>
and now it works! Thanks alot!
Want results from more Discord servers?
Add your server