FilamentPHP:如何基于文本输入值动态设置Select组件maxItems属性
如何基于TextInput值动态更新Filament Select组件的maxItems属性
你的实现思路是完全可行的,Filament本身就支持通过闭包动态配置组件属性,结合live()方法就能实现实时联动。不过可以优化几个细节,让功能更严谨、用户体验更好:
核心逻辑确认
你给TextInput加上live()使输入值实时同步,然后在Select的maxItems中用$get('person_num')动态获取最新输入值,这个逻辑是Filament官方支持的,能正常生效。
优化建议
修正默认值与验证规则的冲突
你设置了default(0)但又加了rules(['min:1']),默认值不满足验证规则,会导致表单加载就报错。建议把默认值改成1:->default(1)同步调整已选值(当人数限制变小时)
当用户把person_num改小,而当前已选的用户数量超过新限制时,仅发通知不够直观,建议自动截断已选值:
在TextInput的链式调用中添加afterStateUpdated:->afterStateUpdated(function (Set $set, Get $get) { $currentUsers = $get('users') ?? []; $maxAllowed = (int)$get('person_num'); if (count($currentUsers) > $maxAllowed) { // 截断到允许的最大数量 $set('users', array_slice($currentUsers, 0, $maxAllowed)); Notification::make() ->title('已自动调整选择数量,符合新的人数限制') ->warning() ->send(); } })优化Select的验证逻辑
可以给Select加一个自定义规则,确保选择数量不超过person_num,避免前端限制被绕过:->rules(function (Get $get) { return [ 'required', function ($attribute, $value, $fail) use ($get) { if (count($value) > (int)$get('person_num')) { $fail('选择的人数不能超过设定的数量'); } } ]; })
完整优化后的代码
Forms\Components\Section::make('Petugas') ->schema([ Forms\Components\TextInput::make('person_num') ->label('Jumlah Petugas') ->required() ->default(1) ->rules(['min:1']) ->live() ->numeric() ->afterStateUpdated(function (Set $set, Get $get) { $currentUsers = $get('users') ?? []; $maxAllowed = (int)$get('person_num'); if (count($currentUsers) > $maxAllowed) { $set('users', array_slice($currentUsers, 0, $maxAllowed)); Notification::make() ->title('已自动调整选择数量,符合新的人数限制') ->warning() ->send(); } }), Forms\Components\Select::make('users') ->label('Petugas') ->relationship('users', 'name') ->maxItems(fn (Get $get): int => (int)$get('person_num')) ->multiple() ->searchable() ->preload() ->required() ->live() ->rules(function (Get $get) { return [ 'required', function ($attribute, $value, $fail) use ($get) { if (count($value) > (int)$get('person_num')) { $fail('选择的人数不能超过设定的数量'); } } ]; }) ->afterStateUpdated(function (Set $set, Get $get, $state): void { if (count($state) > (int)$get('person_num')) { Notification::make() ->title('Jumlah petugas sudah melebihi jumlah yang diinginkan') ->danger() ->send(); } $set('status', count($state) == (int)$get('person_num') ? 'close' : 'open'); }), ])->columns(2),
内容的提问来源于stack exchange,提问作者lazycoder
相关产品推荐
相关产品推荐

