Max Selectable Options in Checkbox List

Hello, Is there any way I can limit the Checkbox list with Max selectable options? I have around 50+ options to select from and I want users to only select any 5 options. After 5 options it should not let the user check any checkbox. currently, I am just preventing this by using rules.
CheckboxList::make('courses')
->label('Select Courses')
->options(ShopProduct::all()->whereNotNull('single_course')->pluck('product_name','single_course'))
->required()
->reactive()
->searchable()
->columns(3)
->gridDirection('row')
->extraAttributes(['class'=>'overflow-y-auto h-96 p-2'])
->rules([
fn (Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) {
if (isset($this->product->automation->shop_trigger_automation['action']) && ($this->product->automation->shop_trigger_automation['action'] === 'select_learning_courses')) {
if($this->product->automation->shop_trigger_automation['quantity'] != count($value)) {
$fail("Please select any {$this->product->automation->shop_trigger_automation['quantity']} courses.");
}
}
},
])
CheckboxList::make('courses')
->label('Select Courses')
->options(ShopProduct::all()->whereNotNull('single_course')->pluck('product_name','single_course'))
->required()
->reactive()
->searchable()
->columns(3)
->gridDirection('row')
->extraAttributes(['class'=>'overflow-y-auto h-96 p-2'])
->rules([
fn (Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) {
if (isset($this->product->automation->shop_trigger_automation['action']) && ($this->product->automation->shop_trigger_automation['action'] === 'select_learning_courses')) {
if($this->product->automation->shop_trigger_automation['quantity'] != count($value)) {
$fail("Please select any {$this->product->automation->shop_trigger_automation['quantity']} courses.");
}
}
},
])
Could anyone please suggest anything? 🙂 Thank you.
Solution:
Does combining your Rule with a closure on disableWhen work? The closure could count how many are selected and return true when it's too many. https://filamentphp.com/docs/3.x/forms/fields/checkbox-list#disabling-specific-options...
Jump to solution
5 Replies
einnlleinhatt_
einnlleinhatt_12mo ago
Using max:5 maybe
Sanchit Patil
Sanchit PatilOP12mo ago
thank you for your reply I can validate it but after the button click what I want is when the user selects 5 options, all other options should get disabled.
DrByte
DrByte12mo ago
The validation rule is an okay way to handle it. It might even be the only way. (EDIT: er, well, not for disabling the rest ... hmmm) You could make the form more performant if there are lots of other fields on the page by telling it to only validate that component, instead of the whole form when the debounce is triggered:
->rules(.....)
->afterStateUpdated(function (Forms\Contracts\HasForms $livewire, Forms\Components\CheckboxList $component) {
// @phpstan-ignore-next-line
$livewire->validateOnly($component->getStatePath());
})
->rules(.....)
->afterStateUpdated(function (Forms\Contracts\HasForms $livewire, Forms\Components\CheckboxList $component) {
// @phpstan-ignore-next-line
$livewire->validateOnly($component->getStatePath());
})
With checkboxes the use of reactive() may be fine, since it requires individual clicks, which are slower than typing in a text field. But I found that changing from reactive to debounce(400) improved page performance on a large form ... when on a textarea field. ... so, again, may not make any diff on CheckboxList.
Solution
DrByte
DrByte12mo ago
Does combining your Rule with a closure on disableWhen work? The closure could count how many are selected and return true when it's too many. https://filamentphp.com/docs/3.x/forms/fields/checkbox-list#disabling-specific-options
Sanchit Patil
Sanchit PatilOP12mo ago
Thanks a lot, mate. this works like a charm. For those who are looking for a similar kinda solution:
->afterStateUpdated(function (HasForms $livewire, CheckboxList $component) {
$livewire->validateOnly($component->getStatePath());
})
->disableOptionWhen(function (Get $get, string $value){
$c = $get('courses');
if(count($c) >= $this->product->automation->shop_trigger_automation['quantity']){
if(!in_array($value,$c)){
return true;
}
}
})
->afterStateUpdated(function (HasForms $livewire, CheckboxList $component) {
$livewire->validateOnly($component->getStatePath());
})
->disableOptionWhen(function (Get $get, string $value){
$c = $get('courses');
if(count($c) >= $this->product->automation->shop_trigger_automation['quantity']){
if(!in_array($value,$c)){
return true;
}
}
})
Want results from more Discord servers?
Add your server