javascript - Vue.js : how to filter a table with a custom filter - Stack Overflow

Table has two columns Name, Age. Searching works by name. As you type the name of user the table will t

Table has two columns Name, Age. Searching works by name. As you type the name of user the table will trim down to the specific user name.

But I want it to be filtered by age using a parison operator < or >.

Code pen link

Html

<div id="demo" class="container">
  <div class="row">
    <div class="col-md-6">
      <input v-model="search" class="form-control" placeholder="Username to search">
    </div>
    <div class="col-md-1">
      <select class="form-control" v-model="searchOperator">
        <option value=">">></option>
        <option value="<"><</option>
      </select>
    </div>
    <div class="col-md-5">
      <input v-model="searchName" class="form-control" placeholder="Age">
    </div>
  </div>
  <table class="table table-striped">
    <thead>
      <tr>
        <th v-repeat="column: columns">
          <a href="#" v-on="click: sortBy(column)" v-class="active: sortKey == column">
            {{ column | capitalize }}
          </a>
        </th>
      </tr>
    </thead>

    <tbody>
      <tr v-repeat="users | filterBy search | orderBy sortKey reverse">
        <td>{{ name }}</td>
        <td>{{ age }}</td>
      </tr>
    </tbody>
  </table>
</div>

Vue :

new Vue({
  el: '#demo',

  data: {
    sortKey: 'name',

    reverse: false,

    searchName: '',

    searchOperator: '',

    searchAge: '',

    columns: ['name', 'age'],

    newUser: {},

    users: [
      { name: 'John', age: 50 },
      { name: 'Jane', age: 22 },
      { name: 'Paul', age: 34 }
    ]
  },

  methods: {
    sortBy: function(sortKey) {
      this.reverse = (this.sortKey == sortKey) ? ! this.reverse : false;

      this.sortKey = sortKey;
    }
  }
});

What is the best approach to achieve this? I tried but nothing seem to be working.

Table has two columns Name, Age. Searching works by name. As you type the name of user the table will trim down to the specific user name.

But I want it to be filtered by age using a parison operator < or >.

Code pen link

Html

<div id="demo" class="container">
  <div class="row">
    <div class="col-md-6">
      <input v-model="search" class="form-control" placeholder="Username to search">
    </div>
    <div class="col-md-1">
      <select class="form-control" v-model="searchOperator">
        <option value=">">></option>
        <option value="<"><</option>
      </select>
    </div>
    <div class="col-md-5">
      <input v-model="searchName" class="form-control" placeholder="Age">
    </div>
  </div>
  <table class="table table-striped">
    <thead>
      <tr>
        <th v-repeat="column: columns">
          <a href="#" v-on="click: sortBy(column)" v-class="active: sortKey == column">
            {{ column | capitalize }}
          </a>
        </th>
      </tr>
    </thead>

    <tbody>
      <tr v-repeat="users | filterBy search | orderBy sortKey reverse">
        <td>{{ name }}</td>
        <td>{{ age }}</td>
      </tr>
    </tbody>
  </table>
</div>

Vue :

new Vue({
  el: '#demo',

  data: {
    sortKey: 'name',

    reverse: false,

    searchName: '',

    searchOperator: '',

    searchAge: '',

    columns: ['name', 'age'],

    newUser: {},

    users: [
      { name: 'John', age: 50 },
      { name: 'Jane', age: 22 },
      { name: 'Paul', age: 34 }
    ]
  },

  methods: {
    sortBy: function(sortKey) {
      this.reverse = (this.sortKey == sortKey) ? ! this.reverse : false;

      this.sortKey = sortKey;
    }
  }
});

What is the best approach to achieve this? I tried but nothing seem to be working.

Share Improve this question edited Jun 15, 2018 at 9:57 Guillaume Georges 4,0204 gold badges16 silver badges34 bronze badges asked Jan 11, 2018 at 7:12 DipDip 1433 silver badges15 bronze badges 2
  • So yeah mean that type name the select operator the age to find the record ? – Gammer Commented Jan 11, 2018 at 7:18
  • Yes thats exactly i want ! – Dip Commented Jan 11, 2018 at 7:18
Add a ment  | 

1 Answer 1

Reset to default 2

The first thing is : v-repeat is deprecated. So you should be using v-for instead.

<tr v-for="user in filteredPersons">
  <td>{{ user.name }}</td>
  <td>{{ user.age }}</td>
</tr>

filteredPersons is the name of a puted function that returns an array :

puted: {
    filteredPersons: function () {
      return this.users
      .filter(this.filterByName)
      .filter(this.filterByAge)
      .sort(this.orderBy);
    }
  }

It filters and sorts the users array by bining two filter functions and one parator function :

methods: {
    filterByName : function(user) {
      // no search, don't filter : 
      if (this.searchName.length === 0) {
        return true;
      }

      return  (user.name.toLowerCase().indexOf(this.searchName.toLowerCase()) > -1);
    }, 
    filterByAge : function (user) {
      // no operator selected or no age typed, don't filter : 
      if (this.searchOperator.length === 0 || this.age.length === 0) {
        return true;
      }

      if (this.searchOperator === '>') {
        return (user.age > this.age); 
      } else  if (this.searchOperator === '<') {
        return (user.age < this.age);
      }      
    }, 
    orderBy : function (userA, userB) {
      let condition = (userA[this.sortKey] > userB[this.sortKey]);
      if (this.reverse) {
        return !condition;
      } else {
        return condition;
      }
    }
  },

Working snippet :

new Vue({
  el: '#demo',

  data: {
    sortKey: 'name',
    reverse: false,
    searchName: '',
    searchOperator: '',
    searchAge: '',
    columns: ['name', 'age'],
    newUser: {},
    search: "",
    name: "",
    age: "",

    users: [
      { name: 'John', age: 50 },
      { name: 'Jane', age: 22 },
      { name: 'Paul', age: 34 },
      { name: 'Kate', age: 15 },
      { name: 'Amanda', age: 65 },
      { name: 'Steve', age: 38 },
      { name: 'Keith', age: 21 },
      { name: 'Don', age: 50 },
      { name: 'Susan', age: 21 }
    ]
  },
  methods: {
    sortBy: function (sortKey) {
      this.reverse = (this.sortKey == sortKey) ? !this.reverse : false;

      this.sortKey = sortKey;
    }, 
    filterByName : function(user) {
      // no search, don't filter : 
      if (this.searchName.length === 0) {
        return true;
      }

      return  (user.name.toLowerCase().indexOf(this.searchName.toLowerCase()) > -1);
    }, 
    filterByAge : function (user) {
      // no operator selected or no age typed, don't filter : 
      if (this.searchOperator.length === 0 || this.age.length === 0) {
        return true;
      }

      if (this.searchOperator === '>') {
        return (user.age > this.age); 
      } else  if (this.searchOperator === '<') {
        return (user.age < this.age);
      }      
    }, 
    orderBy : function (userA, userB) {
      let condition = (userA[this.sortKey] > userB[this.sortKey]);
      if (this.reverse) {
        return !condition;
      } else {
        return condition;
      }
    }
  },
  puted: {
    filteredPersons: function () {
      return this.users
      .filter(this.filterByName)
      .filter(this.filterByAge)
      .sort(this.orderBy);
    }
  },  
});
body {
  margin: 2em 0;
}

a {
  font-weight: normal;
  color: blue;
}

a.active {
  font-weight: bold;
  color: black;
}
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn./bootstrap/3.3.5/css/bootstrap.min.css"/> 
<script src="https://unpkg./[email protected]/dist/vue.js"></script>
<script src="index.js" defer></script>

</head>
<body>
<div id="demo" class="container">
  <div class="row">
    <div class="col-md-6">
      <input v-model="searchName" class="form-control" placeholder="Username to search">
    </div>
    <div class="col-md-1">
      <select class="form-control" v-model="searchOperator">
        <option value=">">></option>
        <option value="<"><</option>
      </select>
    </div>
    <div class="col-md-5">
      <input v-model="age" class="form-control" placeholder="Age" type="number">
    </div>
  </div>
  <table class="table table-striped">
    <thead>
      <tr>
        <th v-for="column in columns">
         <!-- <a href="#" v-on="click: sortBy(column)" >-->
         <!--  <a href="#"> -->
          <a href="#" v-on:click="sortBy(column)" v-bind:class="{active: sortKey == column}">
           
            <!--{{ column | capitalize }}-->
            {{column}}
          </a>
        </th>
      </tr>
    </thead>

    <tbody>
      <tr v-for="user in filteredPersons">
        <td>{{ user.name }}</td>
        <td>{{ user.age }}</td>
      </tr>
    </tbody>
  </table>
</div>
</body>
</html>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745226915a4617503.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信