Validate multiple dynamic fields

hey there. I need to validate muliple dynamic fields in a special way. if you look at the screenshot you see some checkboxes. for each checked checkbox a new field apears. all fields together, summed up, must be 100. how can I validate this?

this is how I generatet the fields:

Forms\Components\CheckboxList::make('materials') ->label(false) ->gridDirection('row') ->columns(2) ->bulkToggleable() ->required() ->live() ->relationship('materials', 'name', modifyQueryUsing: fn (Builder $query) => $query->orderBy('id')), Forms\Components\Fieldset::make(__('backend.materials.fields.plural_share')) ->visible(function(Forms\Get $get) { return $get('materials'); }) ->schema(function(Forms\Get $get) { $fields = []; if($get('materials')) { $materials = Material::whereIn('id',$get('materials'))->pluck('name','id')->toArray(); foreach($get('materials') as $material) { $fields[] = TextInput::make('material_'.$material) ->label($materials[$material]) ->required() ->suffix('%') ->numeric() ->minValue(1) ->maxValue(100); } } return $fields; }),
Bildschirmfoto_2024-05-29_um_15.20.16.png
Solution
Hi there... you could use something like this?

Forms\Components\CheckboxList::make('materials')
    ->label(false)
    ->gridDirection('row')
    ->columns(2)
    ->bulkToggleable()
    ->required()
    ->live()
    ->options([1 => 'material 1', 2 => 'material 2', 3 => 'material 3']),
Forms\Components\Fieldset::make('percentages')
    ->visible(function(Forms\Get $get) {
        return $get('materials');
    })
    ->schema(function(Forms\Get $get) {
        $fields = [];
        if($get('materials')) {
            foreach($get('materials') as $material) {
                $fields[] = TextInput::make('material_'.$material)
                    ->label($material)
                    ->required()
                    ->live()
                    ->suffix('%')
                    ->numeric()
                    ->minValue(1)
                    ->maxValue(100)
                    ->afterStateUpdated(function (Forms\Get $get, Forms\Set $set) {
                        $total = 0;
                        foreach ($get('materials') as $material) {
                            $total += (int)$get('material_'.$material);
                        };
                        $set('total', $total);
                    });
            }
            $fields[] = Forms\Components\TextInput::make('total')
                ->label('Total')
                ->suffix('%')
                ->disabled()
                ->default(0)
                ->rules([
                    fn (): \Closure => function (string $attribute, $value, \Closure $fail) {
                        if ((int)$value !== 100) {
                            $fail('The sum of all the values must be 100.');
                        }
                    },
                ]);
        }
        return $fields;
    })
Was this page helpful?