I need help with selecting the options in a continuous range. For example, as in the image, Q2
and Q4
are selected. I want to implement a functionality such that if a user selects Q2
and Q4
, Q3
gets auto-selected. Similarly, if a user first selects Q3
and then selects Q1
, Q2
gets auto-selected. In summary, upon selection of more than 1 quarters in a continuous range will need to be selected. However, if only one quarter (say Q4
) is selected, the others need not be selected.
component.html
<!-- Select quarter -->
<div
>
<ng-multiselect-dropdown
[placeholder]="'Select quarter(s)'"
[settings]="dropdownSettings"
[data]="quarterList"
[(ngModel)]="selectedQuarterList"
(onDropDownClose)="onDropdownClose()"
(click)="this.isDropdownOpen = true"
>
</ng-multiselect-dropdown>
</div>
component.ts
ngOnInit() {
this.dropdownSettings = {
singleSelection: false,
idField: "quarterId",
textField: "title",
selectAllText: "Select All",
unSelectAllText: "Clear selection",
itemsShowLimit: 4,
allowSearchFilter: false,
};
}
Any help with the same is appreciated, thanks.
CodePudding user response:
A ng-dropdown-select store an array in the variable selectedQuarterList
. The first is order this array, after we get the first and last element of this array (really the index) and select all the values between this one
So, first we add the events (onSelect)
and (onDeSelect)
. I choose the same function passing a new argument that is true -if select- or false -if unselect-
<ng-multiselect-dropdown
...
(onSelect)="onItemSelect($event,true)"
(onDeSelect)="onItemSelect($event,false)"
>
</ng-multiselect-dropdown>
The function onItemSelect becomes like
onItemSelect(event: any, checked: boolean) {
if (this.selectedQuarterList.length > 1) { //almost two elements selected
//we order the elements acording the list
const value=this.quarterList.filter(x=>this.selectedQuarterList.indexOf(x)>=0)
//get the index of the first and the last element
let first = this.quarterList.findIndex((x) => x == value[0]);
let last = this.quarterList.findIndex(
(x) => x == value[value.length - 1]
);
//and give the value between this indexs
this.selectedQuarterList = this.quarterList.filter(
(_, index) => index >= first && (last < 0 || index <= last)
);
}
}
But, with only this code, we can not uncheck an option in middle -imagine you has selected ["Q1","Q2","Q3"]
it's impossible uncheck "Q2" (first get the value 0, last the value 2 and again is selected "Q2"
To take account this we need find the index of the element unselected and change the variables first and last so the function becomes like
onItemSelect(event: any, checked: boolean) {
if (this.selectedQuarterList.length > 1) {
const value=this.quarterList.filter(x=>this.selectedQuarterList.indexOf(x)>=0)
let first = this.quarterList.findIndex((x) => x == value[0]);
let last = this.quarterList.findIndex(
(x) => x == value[value.length - 1]
);
//we add this condition
if (last - first 1 > value.length && !checked) {
const index = this.quarterList.findIndex((x) => x == event);
if (index < this.quarterList.length / 2) {
first = index 1;
} else
last =index-1;
}
this.selectedQuarterList = this.quarterList.filter(
(_, index) => index >= first && (last < 0 || index <= last)
);
}
}
you can see in this stackblitz