F
Filament2mo ago
Veur

Update Select options after event

I have a Select field with options from a database. Now I want to update the list of options after a Livewire event was dispatched. Is this possible?
20 Replies
Veur
Veur2mo ago
@Leandro Ferreira yeah, but my form has a lot of Select fields with own options. The options can be edited inside a modal. So, I'm dispatching an event from the modal to the form, but I don't know how to 'refresh' the select component. I tried $this->dispatch('$refresh'); from the modal, but no luck
LeandroFerreira
LeandroFerreira2mo ago
could you share some code you are trying to do?
Veur
Veur2mo ago
Ok, below is a simplified example:
protected function form(Form $form): Form
{
return $form->schema($fieldsFromDb->map(fn (FormField $field) => Select::make($field->name)->options($field-getOptions()))
->flatten()
->toArray()
);
}
protected function form(Form $form): Form
{
return $form->schema($fieldsFromDb->map(fn (FormField $field) => Select::make($field->name)->options($field-getOptions()))
->flatten()
->toArray()
);
}
$fieldsFromDb is a Collection with fields from the database. getOptions() is a method in the FormField model that returns the options for that specific field. This all works fine, but I don't know how to refresh the list of options.
LeandroFerreira
LeandroFerreira2mo ago
Something like this
Select::make('select')
->options([
'option1' => 'Option 1',
'option2' => 'Option 2',
])
->registerListeners([
'updateOptions' => [
function (Select $component): void {
$component->options([
'option3' => 'Option 3',
'option4' => 'Option 4',
]);
},
],
])
Select::make('select')
->options([
'option1' => 'Option 1',
'option2' => 'Option 2',
])
->registerListeners([
'updateOptions' => [
function (Select $component): void {
$component->options([
'option3' => 'Option 3',
'option4' => 'Option 4',
]);
},
],
])
$this->dispatchFormEvent('updateOptions');
$this->dispatchFormEvent('updateOptions');
Veur
Veur2mo ago
@Leandro Ferreira thanks, but it doesn't work. I added a dd() to the listener callback but nothing happens I'm also trying to find documentation about this feature, but it's not documented
LeandroFerreira
LeandroFerreira2mo ago
Could you share how are you doing this?
Veur
Veur2mo ago
Select::make('select')
->options($field->selectOptions())
->registerListeners([
'updateOptions' => [
function (Select $component) use ($field): void {
dd($component);
$component->options($field->selectOptions());
},
],
])
Select::make('select')
->options($field->selectOptions())
->registerListeners([
'updateOptions' => [
function (Select $component) use ($field): void {
dd($component);
$component->options($field->selectOptions());
},
],
])
And from the modal where the options are managed: $this->dispatchFormEvent('updateOptions'); I also implemented HasForms and added use InteractsWithForms; to the modal.
Veur
Veur2mo ago
LeandroFerreira
LeandroFerreira2mo ago
Where are you using this? $this->dispatchFormEvent('updateOptions')
Veur
Veur2mo ago
In the modal component, after saving the options and before closing the modal The modal is a separate (non-Filament) Livewire component
LeandroFerreira
LeandroFerreira2mo ago
take a look.. if you create a livewire component as this section https://filamentphp.com/docs/3.x/forms/adding-a-form-to-a-livewire-component And add this:
public function form(Form $form): Form
{
return $form
->schema([
Select::make('select')
->options([
'option1' => 'Option 1',
'option2' => 'Option 2',
'option3' => 'Option 3',
])
->registerListeners([
'updateOptions' => [
function (Select $component): void {
$component->options([
'option4' => 'Option 4',
'option5' => 'Option 5',
'option6' => 'Option 6',
]);
},
],
])
])
->statePath('data');
}

public function create(): void
{
$this->dispatchFormEvent('updateOptions');
}
public function form(Form $form): Form
{
return $form
->schema([
Select::make('select')
->options([
'option1' => 'Option 1',
'option2' => 'Option 2',
'option3' => 'Option 3',
])
->registerListeners([
'updateOptions' => [
function (Select $component): void {
$component->options([
'option4' => 'Option 4',
'option5' => 'Option 5',
'option6' => 'Option 6',
]);
},
],
])
])
->statePath('data');
}

public function create(): void
{
$this->dispatchFormEvent('updateOptions');
}
The event will be dispatched when you submit the form
Veur
Veur2mo ago
@Leandro Ferreira yes this is basically what I'm doing, only my form is in another component. Maybe that's the reason it's not working?
LeandroFerreira
LeandroFerreira2mo ago
hum.. maybe
Veur
Veur2mo ago
@Leandro Ferreira one thing I forgot to mention is that the Select field is a multiple select ->multiple() And when I remove that, the options are being refreshed using Livewire's $refresh event. Any idea why it's not working with ->multiple()? The solution with dispatchFormEvent() still won't work btw.
LeandroFerreira
LeandroFerreira2mo ago
because multiple uses choices.js I think
Veur
Veur2mo ago
Is that a bug or expected behavior?
Veur
Veur2mo ago
Ok, thanks!