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.
3 Answers
Reset to default 13Complete 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条)