0
votes

I am trying to build a search inside a table without using any pipes. This is what I have by now:

.ts

  get filteredArray() {
    if (this.searchValue.length === 0) {
      return this.usersList
    }

    return this.usersList.filter((user) => {
      return (this.searchValue.length > 0 ? this.searchValue.indexOf(user.name) !== -1 : true) || 
      (this.searchValue.length > 0 ? this.searchValue.indexOf(user.group) !== -1 : true) || 
      (this.searchValue.length > 0 ? this.searchValue.indexOf(user.age) !== -1 : true)
    })
  }

  inputClick(searchText) {
    if (searchText != "") {
      this.searchValue.push(searchText)
    } else {
      this.searchValue.splice(0, 1)
    }
  }

.html

<input type="text" [(ngModel)]="searchText" (keyup.enter)="inputClick(searchText)">

<table>
  <thead>
    <tr>
      <td><strong>Name</strong></td>
      <td><strong>Group</strong></td>
      <td><strong>Age</strong></td>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let user of filteredArray">
      <td>{{ user.name }}</td>
      <td>{{ user.group }}</td>
      <td>{{ user.age }}</td>
    </tr>
  </tbody>
</table>

This works fine (if you type something inside input and hit ENTER, it will appear, if you delete and hit ENTER, it will revert to the initial array)

As you can see, to do this I filtered through each field of the list:

(this.searchValue.length > 0 ? this.searchValue.indexOf(user.name) !== -1 : true) || 
(this.searchValue.length > 0 ? this.searchValue.indexOf(user.group) !== -1 : true) || 
(this.searchValue.length > 0 ? this.searchValue.indexOf(user.age) !== -1 : true)

My question is: how can I avoid taking all the fields in my return statement? Because in my database I have more than 30 fields and it's hard work to write 30 different ||.

Also, how can I modify my code, if I write joh instead of john, to still find the entry?

Thank you for your time! Here you can see a working snippet of my project

2

2 Answers

1
votes

I would have work with FormControl in a reactive style, but that is not what you asked for.
I modified your solution to get your user properties, and check wheter your searchText matches a value in one of your user property.

See this stackblitz

1
votes

You can write a function to loop through all fields and check for all fields.

containsValue(userObj, searchValue){
    return Object.values(userObj).reduce((prev, cur) => {
        cur = cur.toString();
        return prev || cur.indexOf(searchValue) > -1;
    }, false)
}

Use this method in your current function as

get filteredArray(){
    ...
    return this.userList.filter((user) => this.containsValue(user, this.searchValue));
}

Edit: If you are not using ES2017, then change Object.values() to Object.keys() and get "cur" value as userObj[cur]. So for pre-es2017:

containsValue(userObj, searchValue){
    return Object.keys(userObj).reduce((prev, cur) => {
        let temp = userObj[cur].toString();
        return prev || temp.indexOf(searchValue) > -1;
    }, false);
}