0
votes

I have an issue while working with Angular. I have a drop-down list of items (which actually correspond to the employees of a company), on which I've added a search filter (see the code below), based on the first letters of the name/surname of the employees. I can select more that one option. It works fine if I select one or more items from the list after I filter it. However, if I want to select other additional options that don't match with the filter I've choosen first, I have to change the filter. But it happens that, every time I change the filter, the array containing the selected options (called checkedEmployees) becomes empty. So it seems impossible to select at the same time options that I get by using more than one filter. Is there a solution? Thanks!
This is my html:

<mat-form-field appearance="fill" class="p-1rem" *ngIf="filteredEmployeeOptions && filteredEmployeeOptions.length > 0">
        <input matInput type="text" name="search" placeholder="Search" (ngModelChange)="filterItem($event)" [(ngModel)]="filterText">
        <mat-label>{{'SHARED.EMPLOYEE_NAME' | translate}}</mat-label>
        <mat-select [(ngModel)]="checkedEmployees" name="employeeName" required multiple>
          <mat-option [value]="employee" *ngFor="let employee of filteredEmployeeOptions">         
              {{employee.lastName}} {{employee.firstName}}
          </mat-option>    
        </mat-select>
</mat-form-field>

And this is Typescript:

filterItem(event){
    if(!event){
      this.filteredEmployeeOptions = this.employeeOptions;
    } // when nothing has typed*/   
    if (typeof event === 'string') {
      this.filteredEmployeeOptions = this.employeeOptions.filter(employee => employee.firstName.toLowerCase()
                                          .startsWith(event.toLowerCase()) || employee.lastName.toLowerCase()
                                          .startsWith(event.toLowerCase()));
    }      
}
1

1 Answers

0
votes

As you're changing the range of employees when you query, the filteredEmployeeOptions reduces and the checkedEmployees bases itself on this new reduced array. So, to keep the already selected employees, you'll have to store them into this new array.

But in order to do that, you'll need to have a property ( I assumed id ) that is going to help us preventing duplicates.

Try doing the following to see if it works:

filterItem(event) {
  if(!event)
    this.filteredEmployeeOptions = this.employeeOptions;
  // when nothing has typed*/   
  else if (typeof event === 'string') 
    this.filteredEmployeeOptions = this.employeeOptions
                                    .filter(employee => 
                                        employee.firstName.toLowerCase()
                                        .startsWith(event.toLowerCase()) || employee.lastName.toLowerCase()
                                        .startsWith(event.toLowerCase()))
                                    // now we are keeping the already checkedEmployees
                                    .concat(this.checkedEmployees)
                                    // and then we filter by the id to prevent duplicates
                                    .filter(({ id }, index, newArr) => newArr.findIndex(elm => elm.id === id) === index);
      
}