# \[SOLVED\] Max number of selectable checkboxes

**URL:** <https://discourse.aurelia.io/t/solved-max-number-of-selectable-checkboxes/3397>\
**Category:** Help Requests\
**Created:** [April 15, 2020, 9:18am UTC](https://discourse.aurelia.io/t/solved-max-number-of-selectable-checkboxes/3397 "2020-04-15T09:18:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pauldb8](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/pauldb8/32/1796_2.png) [@Pauldb8](https://discourse.aurelia.io/u/Pauldb8)\
**Post date:** [April 15, 2020, 9:18am UTC](https://discourse.aurelia.io/t/solved-max-number-of-selectable-checkboxes/3397/1 "2020-04-15T09:18:35Z")

</div>

Hello everyone,

I’m new to the Aurelia Framework, I find it quite amazing and like very much the vanilla side of it, and I’m working on a project right now, but I have a question, I would like to know what is the best practice way of limiting the number of checkbox a user can choose out of a certain number:

**ChooseSauceModal.html**  
`<label class="container-checkbox"`  
` repeat.for="sauce of sauces">`  
` ${sauce.name}`  
` <input type="checkbox" id="${sauce.id}"`  
`click.delegate="add(sauce)"`  
`matcher.bind="sauceMatcher"`  
` checked.bind="sauce.checked"`  
`disabled.bind="sauce.disabled"><span class="checkmark"></span>`  
` </label>`

**ChooseSauceModal.ts**  
` add(sauce){`  
` sauce.checked = true;`  
` }`  
` sauceMatcher = (a, b) => a.id === b.id;`

First I know something is not working already, as I cannot select any checkbox. If I add a return true to the add() function then checkbox perform normally. But I want to make sure that no more that 2 checkboxes can be selected at any time and all not selected after \>= 2 become disabled.

Any help would be greatly appreciated,  
Thank you.

---

<div class="post-metadata">

**Author:** ![Sayan751](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/sayan751/32/1861_2.png) [@Sayan751](https://discourse.aurelia.io/u/Sayan751)\
**Post date:** [April 15, 2020, 9:32am UTC](https://discourse.aurelia.io/t/solved-max-number-of-selectable-checkboxes/3397/2 "2020-04-15T09:32:18Z")

</div>

Refer this example: [http://aurelia.io/docs/binding/checkboxes#array-of-objects](http://aurelia.io/docs/binding/checkboxes#array-of-objects) to have the correct binding. You don’t need the `click.delegate` explicitly unless it has a different purpose.

For limiting the selection, you can add validation. There is a validation rule named `maxItems` specifically for this use case. Refer: [http://aurelia.io/docs/plugins/validation#defining-rules](http://aurelia.io/docs/plugins/validation#defining-rules)

---

<div class="post-metadata">

**Author:** ![Pauldb8](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/pauldb8/32/1796_2.png) [@Pauldb8](https://discourse.aurelia.io/u/Pauldb8)\
**Post date:** [April 15, 2020, 9:57am UTC](https://discourse.aurelia.io/t/solved-max-number-of-selectable-checkboxes/3397/3 "2020-04-15T09:57:35Z")

</div>

Thank you for your reply, I’m progressing:

**ChooseSauceModal.html**  
`<label class="container-checkbox"`  
` repeat.for="sauce of sauces">`  
` ${sauce.name}`  
` <input`  
` type="checkbox"`  
` model.bind="sauce"`  
` checked.bind="selectedSauces">`  
` <span class="checkmark"></span>`  
` </label>`

EDITED: I was missing init of validator, still not working though  
**ChooseSauceModal.ts**  
` // Inside class`  
` private sauces: Sauce[] = ApiService.getSauces();`  
` private selectedSauces: Sauce[] = [];`  
` // constructor`  
` constructor(private controller: DialogController,`  
` private vControllerFactory: ValidationControllerFactory){`  
` this.controller = controller;`  
` this.vController =` `vControllerFactory.createForCurrentScope();`  
` this.vController.validateTrigger = validateTrigger.change;`  
` }`  
`//outside class`  
`ValidationRules.ensure("selectedSauces").maxItems(2);`

This seems alright but the validation is not taking place though. Also once this works I would like to change the **label** color based on wheter its corresponding checkbox works. I’ve seen example but it requires a instead of a wrapping label, which I absolutely need for styling.

Thank you.

---

<div class="post-metadata">

**Author:** ![Sayan751](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/sayan751/32/1861_2.png) [@Sayan751](https://discourse.aurelia.io/u/Sayan751)\
**Post date:** [April 15, 2020, 10:47am UTC](https://discourse.aurelia.io/t/solved-max-number-of-selectable-checkboxes/3397/4 "2020-04-15T10:47:42Z")

</div>

> [@Pauldb8](#):
>
> I’m progressing

Great!!

In short, you are missing couple of things.

1. Use the `validate` binding behavior in your view to mark the `selectedSauces` property. It would look something like this `selectedSauces & validate`. This instructs the validation controller to validate the property.
2. Define the rules properly. The `ValidationRules` chain needs to end with an `.on(arg)` where arg will be `this` or `ChooseSauceModal` depending on where you are defining the rules.
3. Lastly on submit don’t forget to call the `controller.validate()` to perform a overall validation.

Even if this suggestion works, it is always good to take a look at the validation docs to use it correctly.

---

<div class="post-metadata">

**Author:** ![Pauldb8](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/pauldb8/32/1796_2.png) [@Pauldb8](https://discourse.aurelia.io/u/Pauldb8)\
**Post date:** [April 15, 2020, 2:19pm UTC](https://discourse.aurelia.io/t/solved-max-number-of-selectable-checkboxes/3397/5 "2020-04-15T14:19:27Z")

</div>

Ok I’ve tried various thing after reading the docs. But I am not closer unfortunately, as I understand this validator is to validate member of classes. In my case each checkbox is its own instance of Sauce class, but I don’t want to validate any of its member, rather the number of instances (checked boxes).

Apparently adding to the repeated.for input the following:  
`checked.bind="selectedSauces"`  
Creates a array of Sauce with only the selected one, good.

Now I get the number of checked boxes, but I would like to watch the change, so I tried:  
` @observable( {changeHandler: 'selectedSaucesChanged'})`  
` private selectedSauces: Sauce[] = [];`  
` selectedSaucesChanged(newValue, oldValue){`  
` console.log("change")`  
` }`  
But it only fires once (why ?) and not anymore when I click on any boxes… So close.

---

<div class="post-metadata">

**Author:** ![Pauldb8](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/pauldb8/32/1796_2.png) [@Pauldb8](https://discourse.aurelia.io/u/Pauldb8)\
**Post date:** [April 15, 2020, 2:57pm UTC](https://discourse.aurelia.io/t/solved-max-number-of-selectable-checkboxes/3397/6 "2020-04-15T14:57:11Z")

</div>

So the problem actually was observing changes on an array of an object, Sauce[].  
As per doc  
[https://aurelia.io/docs/binding/observable-properties#observing-collections](https://aurelia.io/docs/binding/observable-properties#observing-collections)  
I need a collection observer:  
` this.bindingEngine.collectionObserver(this.selectedSauces)`  
` .subscribe(this.selectedSaucesChanged.bind(this))`  
and its corresponding callback function:  
`selectedSaucesChanged(splices: Array<ICollectionObserverSplice<string>>){console.log("change"); }`

This works. Now I will play around with the splice and the array length to disable all non selectedSauces checkbox. This is looking good, thank you.
