javascript - Dynamically Filter an Array of Objects in Vue.js - Stack Overflow

I have a Vue.js app. In this app, I'm trying to dynamically apply filter value to an Array of obje

I have a Vue.js app. In this app, I'm trying to dynamically apply filter value to an Array of objects. Each object in the Array has fields. I'm trying to filter these objects by field values. Each field can be filtered by multiple values.

At this time, I have been unsuccessful in figuring out how to do this filtering. I've tried using JavaScript's baked-in filter function. However, that always returned an empty result set for me. I've put together this Fiddle, which includes this code:

new Vue({
  el: '#app',
  data: {
    currentFilterProperty: '',
    currentFilterValue: '',

    cols: [
      { title: 'Name', prop:'name' },
      { title: 'Age', prop:'age' },
      { title: 'Birthday', prop:'birthday' },      
    ],

    dataFilters: [],
    data: [
      { name:'Patricia Miller', age:69, birthday:'04-15-1948' },
      { name:'Bill Baggett', age:62, birthday:'05-07-1955' },      
      { name:'Maxine Thies', age:21, birthday:'11-28-1995' },      
      { name:'Alison Battle', age:65, birthday:'08-07-1952' },      
      { name:'Dick Triplett', age:25, birthday:'08-27-1982' } 
    ]
  },

  methods: {
    addFilter: function() {
      var f = this.dataFilters[this.currentFilterProperty];
      if (!f) {
        this.dataFilters = {};
        this.dataFilters[this.currentFilterProperty] = [ this.currentFilterValue ];
      } else {
        this.dataFilters[this.currentFilterProperty].push(this.currentFilterValue);
      }

      // How to apply filter?
    }
  }
})

I'm not sure how to apply the filters to the data object.

I have a Vue.js app. In this app, I'm trying to dynamically apply filter value to an Array of objects. Each object in the Array has fields. I'm trying to filter these objects by field values. Each field can be filtered by multiple values.

At this time, I have been unsuccessful in figuring out how to do this filtering. I've tried using JavaScript's baked-in filter function. However, that always returned an empty result set for me. I've put together this Fiddle, which includes this code:

new Vue({
  el: '#app',
  data: {
    currentFilterProperty: '',
    currentFilterValue: '',

    cols: [
      { title: 'Name', prop:'name' },
      { title: 'Age', prop:'age' },
      { title: 'Birthday', prop:'birthday' },      
    ],

    dataFilters: [],
    data: [
      { name:'Patricia Miller', age:69, birthday:'04-15-1948' },
      { name:'Bill Baggett', age:62, birthday:'05-07-1955' },      
      { name:'Maxine Thies', age:21, birthday:'11-28-1995' },      
      { name:'Alison Battle', age:65, birthday:'08-07-1952' },      
      { name:'Dick Triplett', age:25, birthday:'08-27-1982' } 
    ]
  },

  methods: {
    addFilter: function() {
      var f = this.dataFilters[this.currentFilterProperty];
      if (!f) {
        this.dataFilters = {};
        this.dataFilters[this.currentFilterProperty] = [ this.currentFilterValue ];
      } else {
        this.dataFilters[this.currentFilterProperty].push(this.currentFilterValue);
      }

      // How to apply filter?
    }
  }
})

I'm not sure how to apply the filters to the data object.

Share Improve this question asked Nov 17, 2017 at 15:44 user687554user687554 11.2k26 gold badges83 silver badges142 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 13

Complete solution. Best test: add filter Age 62, then Birthday 04-15-1948, then 'tri' in Name Patricia.

new Vue({
  el: '#app',
  data: {
    filteredProperty: 'name',
    query: '',
    activeFilters: [],
    data: [
      {name: 'Patricia Miller', age: 62, birthday: '04-15-1948'},
      {name: 'Bill Baggett', age:62, birthday: '04-15-1948' },
      {name:'Maxine Thies', age:62, birthday:'11-28-1948'},
      {name:'Alison Battle', age:65, birthday:'08-07-1952'},      
      {name:'Dick Triplett', age:25, birthday:'08-27-1982'}
    ]
  },
  puted: {
    filtered () {
      var filtered = this.data
      this.activeFilters.forEach(filter => {
        filtered = filtered.filter(record => {
          return filter.name === 'name'
            ? new RegExp(filter.value, 'i').test(record[filter.name])
            : record[filter.name] == filter.value
        })
      })
      return filtered
    }
  },
  methods: {
    addFilter () {
      this.activeFilters.push({
        name: this.filteredProperty,
        value: this.query
      })
      this.query = ''
    },
    removeFilter (idx) {
      this.activeFilters.splice(idx, 1)
    }
  }
})
<div id="app">
  <div>
    <select v-model="filteredProperty">
      <option value="name">Name</option>
      <option value="age">Age</option>
      <option value="birthday">Birthdate</option>
    </select>
    <input placeholder="filter value" v-model="query">    
    <button @click="addFilter">add filter</button>
  </div>
  <hr>
  <table v-if="activeFilters.length">
    <tr style="width: 100px">
      <th colspan="3">Filters in use:</th>
    </tr>
    <tr v-for="(filter, index) in activeFilters" :key="index">
      <td>{{ _.capitalize(filter.name) }}:</td>
      <td>{{ filter.value }}</td>
      <td style="padding-left: 10px;">
        <a href="#" @click.prevented=removeFilter(index)>
          remove
        </a>
      </td>
    </tr>
  </table>
  <hr v-if="activeFilters.length">
  <table>
    <tbody>
      <tr v-for="(record, index) in filtered" :key="index">
        <td style="padding-right:18px;">{{ record.name }}</td>
        <td style="padding-right:18px;">{{ record.age }}</td>
        <td>{{ record.birthday }}</td>
      </tr>
    </tbody>
  </table>  
</div>

<script src="https://unpkg./vue"></script>
<script src="https://unpkg./lodash"></script>

Take a look the below code. Change your method to a puted property and then the filter can happen automatically without pressing a button. The fiddle always filters by Name so you'll need to make a few adjustments to work for all filter criteria, but it should get you moving in the correct direction.

new Vue({
  el: '#app',
  data: {
    currentFilterProperty: '',
    currentFilterValue: '',  
    cols: [
      { title: 'Name', prop:'name' },
      { title: 'Age', prop:'age' },
      { title: 'Birthday', prop:'birthday' }  
    ],
    data: [
      { name:'Patricia Miller', age:69, birthday:'04-15-1948' },
      { name:'Bill Baggett', age:62, birthday:'05-07-1955' },      
      { name:'Maxine Thies', age:21, birthday:'11-28-1995' },      
      { name:'Alison Battle', age:65, birthday:'08-07-1952' },      
      { name:'Dick Triplett', age:25, birthday:'08-27-1982' } 
    ]
  },
  puted:{
  	filteredData(){
    	var self = this;
        // Add condition for currentFilterProperty == 'Name'
    	if(this.currentFilterValue != undefined && this.currentFilterValue != ''){
      	return this.data.filter(function(d){
        	//alert(d.name + " " + this.currentFilterValue);
      		return d.name.indexOf(self.currentFilterValue) != -1;
      	});          
      }
      // else if(currentFilterProperty == 'Date'){
      // return this.data.filter(function(d){
        	
      		//return d.birthday.indexOf(self.currentFilterValue) != -1;
      //	});
      else{
      	return this.data;
      }    	
    }
  }
})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.4/vue.min.js"></script>

<div id="app">
  <div>
    <select v-model="currentFilterProperty">
      <option v-for="c in cols" :value="c.prop">{{c.title}}</option>
    </select>
    
    <input placeholder="filter value" v-model="currentFilterValue" />
  </div>
  <hr />

  <table>
    <tbody>
      <tr v-for="(record, index) in filteredData">
        <td style="padding-right:18px;">{{ record.name }}</td>
        <td style="padding-right:18px;">{{ record.age }}</td>
        <td>{{ record.birthday }}</td>
      </tr>
    </tbody>
  </table>  
</div>

Here is working solution By checking captaining condition

new Vue({
  el: '#app',
  data: {
    currentFilterProperty: 'name',
    currentFilterValue: '',
    filteredData:[],
    cols: [
      { title: 'Name', prop:'name' },
      { title: 'Age', prop:'age' },
      { title: 'Birthday', prop:'birthday' },      
    ],

    dataFilters: [],
    addFilters:[],
    data: [
      { name:'Patricia Miller', age:69, birthday:'04-15-1948' },
      { name:'Bill Baggett', age:62, birthday:'05-07-1955' },      
      { name:'Maxine Thies', age:21, birthday:'11-28-1995' },      
      { name:'Alison Battle', age:65, birthday:'08-07-1952' },      
      { name:'Dick Triplett', age:25, birthday:'08-27-1982' } 
    ]
  },
  
  methods: {
    addFilter: function() {
     if(!this.currentFilterValue){
      return false;
     }
      var obj = {};
      this.addFilters.push({name:this.currentFilterProperty,value:this.currentFilterValue});
      this.currentFilterValue = "";
    	var vm = this;
      this.dataFilters = this.data
      //var temp = [];
      for(var i in vm.addFilters){
        this.dataFilters = this.dataFilters.filter(function(a,b){
        return ((a[vm.addFilters[i].name]).toString().toLowerCase()).indexOf((vm.addFilters[i].value).toString().toLowerCase()) !== -1;
        });
      }
      // How to apply filter?
    }
  },
  mounted(){
    this.dataFilters = this.data;
  }
})
<script src="https://unpkg./vue"></script>

<div id="app">
  <div>
    <select v-model="currentFilterProperty">
      <option value="name">Name</option>
      <option value="age">Age</option>
      <option value="birthday">Birthdate</option>
    </select>
    <input placeholder="filter value" v-model="currentFilterValue" />
    
    <button v-on:click="addFilter">
    add filter
    </button>
  </div>
  <div v-for="(filter,index) in addFilters">{{filter.name}} : {{filter.value}}</div>
  <hr />

  <table>
    <tbody>
      <tr v-for="(record, index) in dataFilters">
        <td style="padding-right:18px;">{{ record.name }}</td>
        <td style="padding-right:18px;">{{ record.age }}</td>
        <td>{{ record.birthday }}</td>
      </tr>
    </tbody>
  </table>  
</div>

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

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信