最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin0浏览0评论

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>

发布评论

评论列表(0)

  1. 暂无评论