How to Check Unique Field Names Across Sections in Nested Repeater?

The user is filling a form which creates this structure (an array of sections containing fields):
[
{
"name": "Section 1",
"fields": [
{
"name": "Field 1"
},
{
"name": "Field 2"
}
]
},
{
"name": "Section 1",
"fields": [
{
"name": "Field 1"
},
{
"name": "Field 2"
}
]
}
]
[
{
"name": "Section 1",
"fields": [
{
"name": "Field 1"
},
{
"name": "Field 2"
}
]
},
{
"name": "Section 1",
"fields": [
{
"name": "Field 1"
},
{
"name": "Field 2"
}
]
}
]
The problem is that i want the names to be unique. For the sections, is easy:
Forms\Components\Repeater::make('sections')
->schema([
Forms\Components\TextInput::make('name')
->distinct()
Forms\Components\Repeater::make('sections')
->schema([
Forms\Components\TextInput::make('name')
->distinct()
But then, for the fields: I don't know how to specify that I want them to be unique for the current section but also in other sections
Forms\Components\Repeater::make('sections')
->schema([
Forms\Components\TextInput::make('name')
->distinct()
->schema([
Forms\Components\Repeater::make('fields')
Forms\Components\TextInput::make('name')
->distinct() // how to specify that must be distinct in all sections, not only current one?
Forms\Components\Repeater::make('sections')
->schema([
Forms\Components\TextInput::make('name')
->distinct()
->schema([
Forms\Components\Repeater::make('fields')
Forms\Components\TextInput::make('name')
->distinct() // how to specify that must be distinct in all sections, not only current one?
What would u do?
Solution:
solved: ```php use Livewire\Component as Livewire; ......
Jump to solution
1 Reply
Solution
ericmp
ericmp4w ago
solved:
use Livewire\Component as Livewire;

...

Forms\Components\Repeater::make('sections')
->schema([
Forms\Components\TextInput::make('name')
->distinct()
->schema([
Forms\Components\Repeater::make('fields')
Forms\Components\TextInput::make('name')
->rule(function (Get $get, Livewire $livewire): \Closure {
return function (string $attribute, $value, \Closure $fail) use ($livewire): void {
$fieldsNames = collect($livewire->data['sections'])->pluck('fields.*.name')->flatten(depth: 1);

$nameIsRepeated = (function () use ($fieldsNames, $value): bool {
return $fieldsNames->filter(function (string $fieldName) use ($value): bool {
return $fieldName === $value;
})->count() > 1;
})();

if ($nameIsRepeated) {
$fail(__('validation.distinct'));
}
};
})
use Livewire\Component as Livewire;

...

Forms\Components\Repeater::make('sections')
->schema([
Forms\Components\TextInput::make('name')
->distinct()
->schema([
Forms\Components\Repeater::make('fields')
Forms\Components\TextInput::make('name')
->rule(function (Get $get, Livewire $livewire): \Closure {
return function (string $attribute, $value, \Closure $fail) use ($livewire): void {
$fieldsNames = collect($livewire->data['sections'])->pluck('fields.*.name')->flatten(depth: 1);

$nameIsRepeated = (function () use ($fieldsNames, $value): bool {
return $fieldsNames->filter(function (string $fieldName) use ($value): bool {
return $fieldName === $value;
})->count() > 1;
})();

if ($nameIsRepeated) {
$fail(__('validation.distinct'));
}
};
})
if anyone has any improvements, let me know please. ping me
Want results from more Discord servers?
Add your server