phplaravellaravel-filamentfilamentphp

Accessing sibling TextInput state in Repeater default method in Filament 3


I have a Filament Resource with the following form method:

public static function form(Form $form): Form
    {
        return $form
            ->columns(1)
            ->schema([
                Wizard::make([
                    Wizard\Step::make('Duration')
                        ->icon('far-clock')
                        ->completedIcon('fas-clock')
                        ->schema([
                            TextInput::make('weeks')
                                ->label('How long should the plan be?')
                                ->reactive()
                                ->afterStateUpdated(function (callable $set, $state) {
                                    $set('weeks', $state);
                                }),
                        ]),
                    Wizard\Step::make('Schema')
                        ->icon('heroicon-o-table-cells')
                        ->completedIcon('heroicon-s-table-cells')
                        ->schema([
                            Repeater::make('schemas')
                                ->label('')
                                ->schema([
                                    Fieldset::make('Week')
                                        ->columns(12)
                                        ->schema([
                                            TextInput::make('week_from')
                                                ->numeric()
                                                ->minValue(1)
                                                ->maxValue(fn (callable $get) => $get('weeks'))
                                                ->required()
                                                ->label('From')
                                                ->columnSpan(6),
                                            TextInput::make('week_to')
                                                ->numeric()
                                                ->minValue(1)
                                                ->maxValue(fn (callable $get) => $get('weeks'))
                                                ->required()
                                                ->label('To')
                                                ->columnSpan(6),
                                        ]),
                                ])
                                ->required()
                                ->addable()
                                ->deletable()
                                ->cloneable()
                                ->reorderable(false)
                                ->minItems(1)
                                ->maxItems(fn (callable $get) => $get('weeks'))
                                ->defaultItems(fn (callable $get) => $get('weeks') ?: 1)
                                ->default(function (callable $get) {
                                    $weeks = $get('weeks') ?? 1;
                                    dump($weeks);
                                    return [];
                                })
                                ->columns(2),
                        ]),
                ])
            ]);
    }

My goal is to access the state of the "weeks" TextInput in the default method of the Repeater. However, it is not working as expected; dump($weeks); prints "null" instead of the entered value. I also dumped get('./'), and "weeks" is the only element in the returned array.

What am I doing wrong?


Solution

  • I found a solution on my own:

    public static function form(Form $form): Form
    {
        return $form
            ->columns(1)
            ->schema([
                Wizard::make([
                    Wizard\Step::make('Duration')
                        ->icon('far-clock')
                        ->completedIcon('fas-clock')
                        ->schema([
                            TextInput::make('weeks')
                                ->label('How long should the plan be?')
                                ->reactive()
                                ->afterStateUpdated(function (callable $set, $state) {
                                    $set('weeks', $state);
                                    $set('schemas', $this->getSchemaRepeaterState($state['weeks'] ?? 1));
                                }),
                        ]),
                    Wizard\Step::make('Schema')
                        ->icon('heroicon-o-table-cells')
                        ->completedIcon('heroicon-s-table-cells')
                        ->schema([
                            Repeater::make('schemas')
                                ->label('')
                                ->schema([
                                    Fieldset::make('Week')
                                        ->columns(12)
                                        ->schema([
                                            TextInput::make('week_from')
                                                ->numeric()
                                                ->minValue(1)
                                                ->maxValue(fn (callable $get) => $get('weeks'))
                                                ->required()
                                                ->label('From')
                                                ->columnSpan(6),
                                            TextInput::make('week_to')
                                                ->numeric()
                                                ->minValue(1)
                                                ->maxValue(fn (callable $get) => $get('weeks'))
                                                ->required()
                                                ->label('To')
                                                ->columnSpan(6),
                                        ]),
                                ])
                                ->required()
                                ->addable()
                                ->deletable()
                                ->cloneable()
                                ->reorderable(false)
                                ->minItems(1)
                                ->maxItems(fn (callable $get) => $get('weeks'))
                                ->defaultItems(fn (callable $get) => $get('weeks') ?: 1)
                                ->default(function (callable $get) {
                                    $weeks = $get('weeks') ?? 1;
                                    dump($weeks);
                                    return [];
                                })
                                ->columns(2),
                        ]),
                ])
            ]);
    }
    

    In the afterStateUpdated() callback I use $set() to set the content of "schemas". The getSchemaRepeaterState() method is just to format the returned array for my needs. Obviously there is no way to get the state of a sibling if you are in a Repeater.