Last updated on August 21st, 2026 at 01:06 pm
The main lesson: when one Filament form field depends on another, make the source field live and update the derived field explicitly. Keep the derived value read-only and exclude it from saved form data.
What I learned
I needed a select field to show a related slug after the user chose a record. The value also needed to be easy to copy, but it should not be written back to the database.
The reliable pattern has four parts:
- Make the select reactive with
live(). - Use
afterStateUpdated()to respond to the new selection. - Look up the related value with every key needed to identify the record.
- Place the result into a disabled, non-dehydrated text input.
Example
Select::make('destination_id')
->live()
->afterStateUpdated(function ($state, $record, Set $set): void {
$slug = filled($state) && $record
? Item::query()
->where('group_id', $record->group_id)
->where('item_id', $state)
->value('slug')
: null;
$set('destination_slug', $slug);
});
TextInput::make('destination_slug')
->disabled()
->dehydrated(false)
->copyable()
->columnSpanFull();
dehydrated(false) means Filament can display the value without including it in the data saved by the form.
Why the full lookup scope matters
A selected ID is not always globally unique. It may only be unique inside a parent record, tenant, site, or group.
Cause: querying with only the selected ID can return the wrong row.
Fix: include the parent key and the selected key in the query. If the database permits duplicate IDs across groups, both conditions are essential.
Common mistakes
- The value does not update: add
live()to the source field. - The derived field disappears: render it unconditionally and set its value to
nullwhen no option is selected. - The wrong record is loaded: include the complete lookup scope.
- The form tries to save the display value: use
dehydrated(false). - The field is hard to use: make it copyable when users need the value elsewhere.
Practical checklist
- Choose which field triggers the update.
- Mark that field as live.
- Query the related value with all required keys.
- Set the display field from the update callback.
- Test selection, clearing, copying, and saving.
Conclusion
A derived Filament field is simplest when it is treated as display state, not persisted data. The next action is to test both a valid selection and a cleared selection before shipping the form.
