Ionic version: (check one with "x")
[ ] 1.x
[x] 2.x
I'm submitting a ... (check one with "x")
[ ] bug report
[x] feature request
Current behavior:
There is no option to limit the number of selected checkboxes in an AlertController.
Expected behavior:
It is a quite common task to let user select maximum x elements of a list. Would be great if the AlertController could support this by setting a "maxSelectable". Also requiring at least x selected elements is often needed so also "minSelectable" would be great. If maxSelectable is set to 3 and 3 checkboxes have been ticked, the others should be disabled until user unticks one checkbox. In case of minSelectable, if set to > 0, the OK button should be disabled until one element is selected.
I inspected some source codes of Ionic and somehow found something strange:
I thought I could simulate this by setting the "disabled" property of the input as soon as some checkboxes update, so I checked what happens when a checkbox is selected:
cbClick(checkedInput: any) {
if (this.enabled) {
checkedInput.checked = !checkedInput.checked;
if (checkedInput.handler) {
checkedInput.handler(checkedInput);
}
}
}
In case the input has a handler assigned, it will execute it, which would be great, since I could check the number of selected items and disable all which are not yet selected. However, checkedInput can never have a handler property, since its of type AlertInputOptions which does not allow this property, so Typescript always complains if I add a handler property.
export interface AlertInputOptions {
type?: string;
name?: string;
placeholder?: string;
value?: string;
label?: string;
checked?: boolean;
disabled?: boolean;
id?: string;
}
Seems like there is some inconsistency here?
Ok I found a workaround for simulating the maxSelectable attribute. Anyway it would be nice to have this built in. Seems like there is no way for minSelectable right now, but I will handle this in the upper forms "Done" button for now.
In case somebody also needs this before it gets implemented, you can achieve the same like this. Using some type casting allows attaching the "handler" property to the input. Please be aware that you need to reference alert.data.input instead of the original objects you pass into it, since the component creates a copy of each AlertInputOptions instead of referencing it.
Here is my workaround:
let optionHandler = (data : AlertInputOptions) => {
let countChecked = alert.data.inputs.filter((option : AlertInputOptions) => {
return option.checked;
}).length;
alert.data.inputs.forEach((option : AlertInputOptions) => {
option.disabled = !option.checked && countChecked >= MAX_SELECTABLE_TAGS;
});
};
this.tags.forEach((tag: Tag) => {
let checked = this.selectedTagIds.indexOf(tag.id) !== -1;
alert.addInput(<AlertInputOptions>{
type: 'checkbox',
value: tag.id.toString(),
label: tag.name,
checked: checked,
disabled: !checked && this.selectedTagIds.length >= MAX_SELECTABLE_TAGS,
handler: optionHandler
});
});
I'll try your implementation thanks
Any idea on how to implement it with the HTML file? I placed the above code in my .TS file and what about the HTML File? thank you
This issue has been automatically identified as an Ionic 3 issue. We recently moved Ionic 3 to its own repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.
If I've made a mistake, and if this issue is still relevant to Ionic 4, please let the Ionic Framework team know!
Thank you for using Ionic!
Issue moved to: https://github.com/ionic-team/ionic-v3/issues/160
Most helpful comment
Ok I found a workaround for simulating the maxSelectable attribute. Anyway it would be nice to have this built in. Seems like there is no way for minSelectable right now, but I will handle this in the upper forms "Done" button for now.
In case somebody also needs this before it gets implemented, you can achieve the same like this. Using some type casting allows attaching the "handler" property to the input. Please be aware that you need to reference alert.data.input instead of the original objects you pass into it, since the component creates a copy of each AlertInputOptions instead of referencing it.
Here is my workaround: