F
Filament10mo ago
Patrick

How to implement a dynamic form in an action

I would like to display fields based on a database entry. I have this action:
Action::make('Opleiding inplannen')
->form([
Select::make('education_id')
->label('')
->options(Education::orderBy('name', 'asc')->pluck('name', 'id'))
->required()
->live()
->afterStateUpdated(fn (Select $component) => $component
->getContainer()
->getComponent('planningForm')
->getChildComponentContainer()
->fill()
),
Grid::make(2)
->schema(function(Get $get){

$educationId = $get('education_id');

if($educationId){
return Educations::getPlanningFormSchemaArray(
Education::find($educationId)
);
}

return [];
})
->key('planningForm')

])
->action(function(array $data){

})
->slideOver()
->after(function($data){
$url = route('filament.admin.resources.education.edit', ['record' => $data['education_id']]).'?openPlanningForm=true';
return redirect($url);
}),
Action::make('Opleiding inplannen')
->form([
Select::make('education_id')
->label('')
->options(Education::orderBy('name', 'asc')->pluck('name', 'id'))
->required()
->live()
->afterStateUpdated(fn (Select $component) => $component
->getContainer()
->getComponent('planningForm')
->getChildComponentContainer()
->fill()
),
Grid::make(2)
->schema(function(Get $get){

$educationId = $get('education_id');

if($educationId){
return Educations::getPlanningFormSchemaArray(
Education::find($educationId)
);
}

return [];
})
->key('planningForm')

])
->action(function(array $data){

})
->slideOver()
->after(function($data){
$url = route('filament.admin.resources.education.edit', ['record' => $data['education_id']]).'?openPlanningForm=true';
return redirect($url);
}),
Now the
Educations::getPlanningFormSchemaArray
Educations::getPlanningFormSchemaArray
returns an array with a schema However, when i select an education the initial value just gets reset in the select instead of seeing the new form. How can i do this?
1 Reply
Patrick
PatrickOP10mo ago
The form fields i want to display:
public static function getPlanningFormSchemaArray(Education $education)
{
$schema = [];
foreach($education->courses as $course){
$schema[$education->id] = Fieldset::make($course->name)
->schema([
DatePicker::make('start_date.'. $course->id)
->label('Datum')
->required(),
TimePicker::make('start_time.'. $course->id)
->label('Starttijd')
->required(),
TimePicker::make('end_time.'. $course->id)
->required()
->label('Eindtijd'),
Select::make('location.'.$course->id)
->options(
Location::orderBy('name')->pluck('name', 'id')
)
->default(
Location::where('name', 'Company')->first()?->id
)
->label('Locatie')
->required(),
]);
}

return $schema;
}
public static function getPlanningFormSchemaArray(Education $education)
{
$schema = [];
foreach($education->courses as $course){
$schema[$education->id] = Fieldset::make($course->name)
->schema([
DatePicker::make('start_date.'. $course->id)
->label('Datum')
->required(),
TimePicker::make('start_time.'. $course->id)
->label('Starttijd')
->required(),
TimePicker::make('end_time.'. $course->id)
->required()
->label('Eindtijd'),
Select::make('location.'.$course->id)
->options(
Location::orderBy('name')->pluck('name', 'id')
)
->default(
Location::where('name', 'Company')->first()?->id
)
->label('Locatie')
->required(),
]);
}

return $schema;
}
the form does not have a fixed set of fields, but its dependant on how many courses there are oh i fixed it somehow
->afterStateUpdated(fn (Select $component) => $component
->getContainer()
->getComponent('planningForm')
->getChildComponentContainer()
->fill()
)
->afterStateUpdated(fn (Select $component) => $component
->getContainer()
->getComponent('planningForm')
->getChildComponentContainer()
->fill()
)
I removed the fill method, now its just displaying the form mm without calling fill it wont set any default values it seems Select::make('location.'.$course->id) ->options( Location::orderBy('name')->pluck('name', 'id') ) ->default( Location::where('name', 'Company')->first()?->id ) ->label('Locatie') ->required(),
Want results from more Discord servers?
Add your server