F
Filament8mo ago
Wbzy

How to listen to dispatch events in form?

so i have a button for populating the repeater, basically the button will open a modal and inside a modal there is a livewire filament table. in the bulk action i want to dispatch selected data back to the form. This is my button
Forms\Components\Actions\Action::make('add')
->hiddenLabel()
->color('success')
->tooltip('Add Invoice')
->icon('heroicon-o-plus-circle')
->modalHeading('Choose Invoice')
->modalSubmitAction(false)
->modalContent(view('filament.modal.invoice-table'))
->action(function (Forms\Get $get, Forms\Set $set, Component $livewire) {
// I want to get the selected record from modal and set the repeater here
}),
Forms\Components\Actions\Action::make('add')
->hiddenLabel()
->color('success')
->tooltip('Add Invoice')
->icon('heroicon-o-plus-circle')
->modalHeading('Choose Invoice')
->modalSubmitAction(false)
->modalContent(view('filament.modal.invoice-table'))
->action(function (Forms\Get $get, Forms\Set $set, Component $livewire) {
// I want to get the selected record from modal and set the repeater here
}),
This is my bulk action
->bulkActions([
BulkAction::make('select')
->action(fn (Collection $records) => $this->dispatch('selectedData', selectedData: $records)),
]);
->bulkActions([
BulkAction::make('select')
->action(fn (Collection $records) => $this->dispatch('selectedData', selectedData: $records)),
]);
No description
No description
Solution:
in the table bulk action i use 2 dispatch one for passing the data, and the other for closing the modal. ```php $livewire->dispatch('attach-record', data: $record->select(['id'])->first());...
Jump to solution
12 Replies
Wbzy
Wbzy8mo ago
or is there any other way to pass the data ?
toeknee
toeknee8mo ago
Hmmm..... you can try $set('../parent_fieldss') basically traversing with ../../
ziolupo
ziolupo7mo ago
Did you solve the issue? I 'm interested in the solution
Wbzy
Wbzy7mo ago
i did
Solution
Wbzy
Wbzy7mo ago
in the table bulk action i use 2 dispatch one for passing the data, and the other for closing the modal.
$livewire->dispatch('attach-record', data: $record->select(['id'])->first());
$livewire->dispatch('close-modal', id: $this->componentId.'-form-component-action');
$livewire->dispatch('attach-record', data: $record->select(['id'])->first());
$livewire->dispatch('close-modal', id: $this->componentId.'-form-component-action');
and listen it in the create file
#[On('attach-record')]
public function useRecord($data)
{
$this->data['id'] = $data['id'];
}
#[On('attach-record')]
public function useRecord($data)
{
$this->data['id'] = $data['id'];
}
ziolupo
ziolupo7mo ago
mmhh... very interesting... You put the listener in the create page... interesting.. pages are livewire object... resources are not! Maybe is this my problem! During the weekend I will try to adapt your solution to my needs and I will let you know. Thank you for showing the way! (This is the way...cit.) Dear Wbzy, the dispatch for data is working like a charm. What I'm not able to do is closing the modal. My modal was open in this way:
->suffixAction(
Action::make('findContact')
->icon('heroicon-o-question-mark-circle')
->action(function (Forms\Get $get, Forms\Set $set, Component $livewire){
dd($livewire);
})
->color('primary')
->iconButton()
->modalHeading('Find Contact')
->modalContent(view('filament.modal.contacttable'))
->slideOver()
)
->suffixAction(
Action::make('findContact')
->icon('heroicon-o-question-mark-circle')
->action(function (Forms\Get $get, Forms\Set $set, Component $livewire){
dd($livewire);
})
->color('primary')
->iconButton()
->modalHeading('Find Contact')
->modalContent(view('filament.modal.contacttable'))
->slideOver()
)
I don't have any idea how can I close it. I don't know the id or name... or what is needed here:

$livewire->dispatch('close-modal', id: $this->componentId.'-form-component-action');

$livewire->dispatch('close-modal', id: $this->componentId.'-form-component-action');
Wbzy
Wbzy7mo ago
you need to pass the livewire id to the view like this
->modalContent(function (Component $livewire, Forms\Get $get) {
return view('filament.modal.tablemodal', [
'componentId' => $livewire->getId(),
'customerId' => $get('customer_id'),
]);
})
->modalContent(function (Component $livewire, Forms\Get $get) {
return view('filament.modal.tablemodal', [
'componentId' => $livewire->getId(),
'customerId' => $get('customer_id'),
]);
})
and mount it in your table livewire component
// in blade
<livewire:bank-in-table-modal
:componentId="$componentId"
:customer_id="$customerId"
/>

// in livewire
public ?string $componentId = null;

public ?string $customer_id = null;

public function mount($componentId, $customer_id)
{
$this->componentId = $componentId;
$this->customer_id = $customer_id;
}
// in blade
<livewire:bank-in-table-modal
:componentId="$componentId"
:customer_id="$customerId"
/>

// in livewire
public ?string $componentId = null;

public ?string $customer_id = null;

public function mount($componentId, $customer_id)
{
$this->componentId = $componentId;
$this->customer_id = $customer_id;
}
ziolupo
ziolupo7mo ago
I got it! Now I can close the modal. I have to thank you for your support. There is just one problem yet, sorry if I abuse of your patience. The problem is something I didn't think about in the beginning when I started with this approch and it is the following. My action is done in this way:
Action::make('findContact')
->icon('heroicon-o-question-mark-circle')
->action(function (Component $livewire, Set $set, array $data, ?Contact $record): void {
Log::info("Setting the form");
if($livewire->contact_id){
$contatto=Contact::find($livewire->contact_id);
$set('contact_id',$contatto->id);
$set('country',$contatto->country);
}
})
->color('primary')
->iconButton()
->modalHeading('Find Contact')
->modalContent(function (Component $livewire, Forms\Get $get) {
return view('filament.modal.contacttable', [
'componentId' => $livewire->getId(),
]);
})
->slideOver()
)
Action::make('findContact')
->icon('heroicon-o-question-mark-circle')
->action(function (Component $livewire, Set $set, array $data, ?Contact $record): void {
Log::info("Setting the form");
if($livewire->contact_id){
$contatto=Contact::find($livewire->contact_id);
$set('contact_id',$contatto->id);
$set('country',$contatto->country);
}
})
->color('primary')
->iconButton()
->modalHeading('Find Contact')
->modalContent(function (Component $livewire, Forms\Get $get) {
return view('filament.modal.contacttable', [
'componentId' => $livewire->getId(),
]);
})
->slideOver()
)
As you can see in ->action I'm setting the value of some fields using what I have received through the dispatch. This is working perfectly if I hit "SAVE" (or somthing similar) in the modal. But if I'm closing the modal programmatically the function in -> action() is never called. So most probably I have to set the values from here:
#[On('foundContact')]
public function foundContact($contact_id)
{
// $this->contatto=Contact::find($contact_id);
$this->contact_id=$contact_id;

--->>> HERE I HAVE TO SET THE COMPONENT <<<---
}
#[On('foundContact')]
public function foundContact($contact_id)
{
// $this->contatto=Contact::find($contact_id);
$this->contact_id=$contact_id;

--->>> HERE I HAVE TO SET THE COMPONENT <<<---
}
But I didn't find a way. Later I will check into the filament source code to see if there is an hint for doing that. . Thank you again
Wbzy
Wbzy7mo ago
you can set the data after listen it, maybe something like this?
#[On('foundContact')]
public function foundContact($contact_id)
{
Log::info("Setting the form");
$contatto = Contact::find($contact_id);

$this->data['contact_id'] = $contatto->id;
$this->data['country'] = $contatto->country;
}
#[On('foundContact')]
public function foundContact($contact_id)
{
Log::info("Setting the form");
$contatto = Contact::find($contact_id);

$this->data['contact_id'] = $contatto->id;
$this->data['country'] = $contatto->country;
}
ziolupo
ziolupo7mo ago
So easy! I owe you a beer! Or maybe two!
Wbzy
Wbzy7mo ago
no problem, glad it helps!
ziolupo
ziolupo7mo ago
I just find a different solution: instead of passing the component_id and modifying the blade file for accepting it, you can do something like this in foundContact()
#[On('foundContact')]
public function foundContact($contact_id)
{
$this->dispatch('close-modal', id: $this->getId().'-form-component-action');
$this->contact_id=$contact_id;
$contact=Contact::find($contact_id);
$this->data['contact_id'] = $contact_id;
$this->data['country'] = $contact->country;
$this->data['company'] = $contact->societa;
}
#[On('foundContact')]
public function foundContact($contact_id)
{
$this->dispatch('close-modal', id: $this->getId().'-form-component-action');
$this->contact_id=$contact_id;
$contact=Contact::find($contact_id);
$this->data['contact_id'] = $contact_id;
$this->data['country'] = $contact->country;
$this->data['company'] = $contact->societa;
}
Didn't know which is the best approach