Home > other >  Angular table filter clearing group
Angular table filter clearing group

Time:11-14

I have 2 filters on a user list. A user can select a group containing members and use the search filter to search by last name. When the user backspaces a user to look for another, this resets the groups to all users. I need this to only show the users in the selected group.

TS

  updateFilter(event) {
    const val = event.target.value.toLowerCase();
    const temp = this.temp.filter(function (d) {
      return d.lastName.toLowerCase().indexOf(val) !== -1 || !val;
    });

    this.rows = temp;
    if (this.table) {
      this.table.offset = 0;
    }
  }

  onGroupSelected($event) {
    const groupId = $event.target ? $event.target.value : $event;
    if (groupId === 'none') {
      this.rows = this.temp;
    } else {
      const groupUsers = this.groupUserMap.get(groupId);
      if (groupUsers) {
        this.rows = this.temp.filter((serviceUser) => 
        groupUsers.includes(serviceUser.id));
      } else {
        this.rows = [];
      }
    }
    // @ts-ignore
    this.userSelections = this.userSelections ? this.userSelections : {};
    this.userSelections.groupId = groupId;
    localForage.setItem(this.username, this.userSelections);
  }

HTML

 <input
   type='text'
   class="form-control w-200px"
   placeholder='Search by Last Name...'
   (keyup)='updateFilter($event)'
 />

<select class="form-control w-200px" (change)="onGroupSelected($event)">
    <option value="none">All service users</option>
    <option *ngFor="let group of groups"
        [value]="group.id"
        [selected]="userSelections.groupId === group.id">
        {{group.name}}
    </option>
</select>

CodePudding user response:

You can use ngModel with tow-way binding, to save and manipulate search filters:

<select
  class="form-control w-200px"
  [(ngModel)]="selectedGroup"
  (change)="onGroupSelected()"
>
  <option value="none">All service users</option>
  <option *ngFor="let group of groups" [value]="group.id">
    {{ group.name }}
  </option>
</select>
<input
  type="text"
  class="form-control w-200px"
  placeholder="Search by Last Name..."
  [(ngModel)]="search"
  (keyup)="updateFilter()"
/>

And in order not to lose your users table you can create a copy which will be filtered and displayed.

  public initialUsers = [
    { id: 100, groupId: 1, name: 'foo' },
    { id: 101, groupId: 2, name: 'bar' },
    { id: 102, groupId: 1, name: 'john' },
    { id: 103, groupId: 2, name: 'doe' },
    { id: 104, groupId: 2, name: 'baaar' },
    { id: 105, groupId: 1, name: 'fooodoe' },
  ];

  public filteredUsers = [];

  ngOnInit(): void {
    this.filteredUsers = this.initialUsers;
  }

Here is a demo on stackblitz, I used a list to go fast but It's just display. You just have to replace <ul> <li></li> </ul> by your <table> ... </table>

CodePudding user response:

If you would want to take an observable way of doing this, then I would suggest to make a form of your controls, ooooor just use 2 form controls instead. I chose form here as it wraps it up nicely with both form controls (search and dropdown):

form: FormGroup;

constructor(private fb: FormBuilder) {
  this.form = this.fb.group({
    search: [''],
    group:  [0] // "all" option as initial id
  })
}

Then we would listen to when the form value changes and assign the filtered data to a variable, here named filteredUsers$.

this.filteredUsers$ = this.form.valueChanges.pipe(
  startWith(this.form.value), // to trigger initially
  // 'this.users' refers to your original users array
  map((value: any) => {
    // 'all' option is chosen, just filter based on search
    if (value.group === 0) return this.users.filter(x => x.lastName.toLowerCase().includes(value.search))
    // filter by group and search 
    return this.users.filter(x => {
      return (x.groupId === value.group) && (x.lastName.toLowerCase().includes(value.search.toLowerCase()))
    })
  })
)

That is it, then we just iterate filteredUsers$ in the template:

<tr *ngFor="let user of filteredUsers$ | async">

Of course we need the form in the view and it would look like this:

<form [formGroup]="form">
  <input
    type="text"
    placeholder="Search by Last Name..."
    formControlName="search"
  />

  <select formControlName="group">
    <option *ngFor="let group of groups" [ngValue]="group.id">
      {{ group.name }}
    </option>
  </select>
</form>

Here is a DEMO with the above code

  • Related