Home > Net >  how to detect value is present under any of the array inputs using angular
how to detect value is present under any of the array inputs using angular

Time:06-07

I am working on angular13, here i am showing input under each header column and based on input added under any of the input filter section, filtering happens, but here i want to detect if there is any input present under any of the inputs, if so then filtering must be based on any of those values.

Issue is:

  1. i have given input for one header section, so filtering has happened, now i gave some values for second input, so further filtering has performed, now if i clear value under any of the input, it gives me all the values instead of giving for the filtered values.

TS:

filterCol(event, column) {
    console.log(event, column);
    console.log(this.listOriginal, 'this.listOriginal');
    let keys = Object.keys(this.list[0]);
    let flag = keys.map((x) => {
      if (x == column) {
        return true;
      }
    });
    if (flag && event) {
      this.list = this.list.filter((obj: any) =>
        obj[column].toString().toLowerCase().includes(event)
      );
    } else {
      this.list = this.listOriginal;
    }
  } 

HTML:

<div >
  <table >
    <thead>
      <tr>
        <th
          scope="col"
          *ngFor="let field of headerColumn"
          
        >
          {{ field.columnDisplayName }}
          <i  aria-hidden="true"></i>
          <input style="display:block"
            type="text"
            (input)="filterCol($event.target.value,field.columnName)"
          />
        </th>
      </tr>
    </thead>
    <tbody>
      <ng-container *ngFor="let item of list; let i = index">
        <tr>
          <td
            *ngFor="let field of headerColumn"
            
            title="{{ item[field.columnName] }}"
          >
            <ng-container> {{ item[field.columnName] }} </ng-container>
          </td>
        </tr>
      </ng-container>
    </tbody>
  </table>
</div>

DEMO

Issue example:

  1. I gave input value as "h" under second column(i.e) Name column, so it gave me 3 filtered values, and gave position value as 1, so the filter gave me only one value in the table, now i gave as 10 for position value, so it was empty, now if i remove 10 under position column, then also the value is empty, but i need to show the values based on values added in any of the input, so its like under one input if all values are cleared, it must check if there is value under any input field and give values accordingly.

CodePudding user response:

The reason that filtering stopped working is because you're using the changing this.list. If this.list is an empty array then the filtering will stop working.

To make it work for multiple columns (as per your comment) you have to refactor the code.

First I would add a filter field in the header column. I'm that way you can bind all the header inputs to a variable you can use in the component.

headerColumn = [
  { filter: '', columnName: 'position', columnDisplayName: 'Position' },
  { filter: '', columnName: 'name', columnDisplayName: 'Name' },
  { filter: '', columnName: 'weight', columnDisplayName: 'Weight' },
  ...
]

Then add the filter field to the inputs and remove the paramaters to the filterCol() function.

<input
  style="display: block"
  type="text"
  [(ngModel)]="field.filter"
  (input)="filterCol()"
/>

Change the filterCol() function to take into account all the filled filter inputs and use that

filterCol() {
  let filteredList = this.listOriginal;
  this.headerColumn.forEach((el) => {
    if (el.filter.length > 0) {
      filteredList = filteredList.filter((obj:any) => 
        obj[el.columnName]
          .toString()
          .toLowerCase()
          .includes(el.filter.toLowerCase())
      );
    }
  });
  console.log('filteredlist', filteredList);
  this.list=filteredList;
}

This now looks at all the inputs and when you change one of them it uses them all to filter.

Result : https://stackblitz.com/edit/angular-d4zbgv-pkue3f?file=app/table-selection-example.ts

  • Related