Home > OS >  ng-multiselect-dropdown select options in a continuous range
ng-multiselect-dropdown select options in a continuous range

Time:11-03

I am using Multi-select dropdown

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

  • Related