Default values not applied in dynamically created form

I have the method below to dynamically build a form based on a JSON structure in a spatie settings row. The idea is create this form, fill it with the predefined default values from the DB and if I change something it changes it in the DB. This worked flawlessly with a flat array of key-value pairs. Now I needed to nest it and make it one layer deeper and it does not work anymore. When I ddd my fields or sections, I can see the default values but in the rendered form in the browser they are not there. This is the method to generate the form: I am assuming it does not work because of using $typeKey and $safeKey and same matching does not work? I don't know really... I needed to create the $safeKey because Livewire would not render the page itself with using only $typeKey, I think because of some escaping issues. Code is in the first answer (character limit)
Solution:
I used afterStateHydrated now to fill the config values into the fields. instead of default(). Seems to work for now.
Jump to solution
6 Replies
aldec
aldecOP2w ago
protected function generateApplicationFieldConfigurations(): array
{
$sections = [];
$settings = app(RoadworksSettings::class);

foreach (ApplicationType::cases() as $applicationType) {
$typeKey = $applicationType->value;
// Sanitize the key for use in state paths
$safeKey = Str::slug($typeKey, '_');

$configurations = $settings->fieldConfigurations[$typeKey] ?? [];
$fields = [];

foreach ($configurations as $fieldKey => $config) {
$fields[] = Section::make(Str::title(str_replace('_', ' ', $fieldKey)))
->schema([
Toggle::make("fieldConfigurations.{$safeKey}.{$fieldKey}.visible")
->label('Anzeigen')
->default($config['visible']),
Toggle::make("fieldConfigurations.{$safeKey}.{$fieldKey}.required")
->label('Pflichtfeld')
->default($config['required']),
TextInput::make("fieldConfigurations.{$safeKey}.{$fieldKey}.label")
->label('Bezeichnung')
->required()
->default($config['label']),
TextInput::make("fieldConfigurations.{$safeKey}.{$fieldKey}.helper_text")
->label('Hilfetext')
->default($config['helper_text']),
])
->collapsible();
}

$sections[] = Section::make($typeKey)
->schema($fields)
->collapsed();

}

return $sections;
}
protected function generateApplicationFieldConfigurations(): array
{
$sections = [];
$settings = app(RoadworksSettings::class);

foreach (ApplicationType::cases() as $applicationType) {
$typeKey = $applicationType->value;
// Sanitize the key for use in state paths
$safeKey = Str::slug($typeKey, '_');

$configurations = $settings->fieldConfigurations[$typeKey] ?? [];
$fields = [];

foreach ($configurations as $fieldKey => $config) {
$fields[] = Section::make(Str::title(str_replace('_', ' ', $fieldKey)))
->schema([
Toggle::make("fieldConfigurations.{$safeKey}.{$fieldKey}.visible")
->label('Anzeigen')
->default($config['visible']),
Toggle::make("fieldConfigurations.{$safeKey}.{$fieldKey}.required")
->label('Pflichtfeld')
->default($config['required']),
TextInput::make("fieldConfigurations.{$safeKey}.{$fieldKey}.label")
->label('Bezeichnung')
->required()
->default($config['label']),
TextInput::make("fieldConfigurations.{$safeKey}.{$fieldKey}.helper_text")
->label('Hilfetext')
->default($config['helper_text']),
])
->collapsible();
}

$sections[] = Section::make($typeKey)
->schema($fields)
->collapsed();

}

return $sections;
}
Mohamed Ayaou
Mohamed Ayaou2w ago
Yeah, the ->default() method is static and works only on the first render I think, you have to use a full dynamic option to mutate the fields after form creation
aldec
aldecOP2w ago
Ok... but does it render multiple time? When I visit the page, the form is build and filled with the default values. I see the form fields with correct default when I dump them during this method above. Why are they lost when I actually see the form in the browser? Is there another render happening which... deletes the default values?
Mohamed Ayaou
Mohamed Ayaou2w ago
There's always renders on each LW server request, but this is Livewire specific question, just search about this behavior
toeknee
toeknee2w ago
default is only appiled on 'Creation' and on boot when livewire initiates, if you pass in an array of data to fill the form and the array doesn't have the values they won't be set as we take the form data as primary. You should probably pass in a Setter to set the values creating the schema.
Solution
aldec
aldec2w ago
I used afterStateHydrated now to fill the config values into the fields. instead of default(). Seems to work for now.

Did you find this page helpful?