Oct 13, 2025
0
Level 1
Filament 3: Enforce unique “name” across nested Builder/Repeater items and show per-field errors (not parent)
Question
- Goal: Prevent duplicate field name values in a dynamic form builder, and show the validation error next to the offending TextInput, not at the end of the builder.
- Structure: A SectionsBuilder (custom) contains a FormBuilder (custom). Each form field has a TextInput::make('name').
What I tried:
- Added ->distinct() to the shared TextInput('name') used by all field components (Filament 3.2).
- Tried parent-level ->rule() closures on SectionsBuilder / FormBuilder that scan the array and call $fail(...).
Problems:
- ->distinct() doesn’t seem to enforce uniqueness across items spanning multiple sections (nested structure).
- Parent ->rule() validates, but the error shows on the parent component (bottom of the builder), not on the specific name inputs.
How can I:
- Enforce uniqueness of name across all items, including across sections.
- Show validation errors next to each duplicate TextInput('name'), not only on the parent?
Environment:
- Filament 3.2
Relevant code (from my project)
private function getNameAttribute(): TextInput
{
return TextInput::make('name')
->label(__('form-builder.props.name'))
->helperText(__('form-builder.helpers.name'))
->alphaDash()
->required()
->distinct()
->minLength(2)
->maxLength(50)
->autofocus()
->autocomplete(false);
}
return [
SectionsBuilder::make('schema.sections')->schema([
FormBuilder::make('fields')
->formComponents([
StringField::class,
NumberField::class,
CheckboxField::class,
TextareaField::class,
SelectField::class,
DateField::class,
Header::class,
Paragraph::class,
SignatureField::class,
PhoneNumberField::class,
])
->componentPickerColumns()
->data([
'docTypes' => $this->documentTypes,
])
->preview($this->getRecord()->status == SchemaStatus::Archived)
->afterStateUpdated(function () {
if ($this->getRecord()->status == SchemaStatus::Draft) {
$this->save(shouldSendSavedNotification: false);
}
}),
])
// ...
];
Minimal reproducible (simplified)
Builder::make('sections')->schema([
// Each section has nested fields
Repeater::make('fields')->schema([
TextInput::make('name')->required()->distinct(), // want uniqueness across ALL sections
]),
]);
Desired behavior:
If two items anywhere (even across sections) have the same name, show the error directly under each offending TextInput, not on the parent.
Questions
- Does ->distinct() support cross-nested validation scopes, or only direct siblings within a single repeater/builder?
- If cross-section uniqueness needs a parent-level rule, how can I map failures to each duplicate child field so errors render on the corresponding TextInput('name')?
- Is there a recommended Filament 3 way to assign validation errors to specific nested item paths (e.g., sections.0.fields.2.name
) from a parent->rule() closure?
Please or to participate in this conversation.