Since in Vue 2.0 you can no longer chain together multiple pipeline filters to a list (|filterBy
etc), how are you supposed to do this in a puted property if you have two or more select dropdowns?
I want the ability to sort by album title (from select 1) and by year (select 2).
<select v-model="albumFilter">
<option value="All">All</option>
<option value="Album 1">Album 1</option>
<option value="Album 2">Album 2</option>
<option value="Album 3">Album 3</option>
</select>
<select v-model="yearFilter">
<option value="Year">Year</option>
<option value="2017">2017</option>
<option value="2016">2016</option>
<option value="2015">2015</option>
</select>
<ul>
<li v-for="review in filterByAlbum" v-if="review.type === 'recordReview'">
<a :href="review.jsonUrl">
[[ review.title ]]
</a>
</li>
</ul>
Vue js code:
data() {
return {
pressEntries: [],
albumFilter: 'All',
yearFilter: 'Year'
}
},
filterByAlbum: function() {
// Select 1 (Album Filter)
switch (this.albumFilter) {
case 'All':
return this.pressEntries;
break;
case 'Neither':
return this.pressEntries.filter(entry => {
return entry.relatedRecording === null
});
break;
default:
return this.pressEntries.filter(entry => {
return entry.relatedRecording === this.albumFilter
});
}
// Select 2 (Year Filter)
if (this.yearFilter === 'Year') {
return this.pressEntries;
}
else {
return this.pressEntries.filter(entry => {
let postDate = new Date(entry.postDate.date);
return JSON.stringify(postDate.getFullYear()) === this.yearFilter;
});
}
}
The pressEntries
data model gets data from an API, which I didn't bother including the code for. Each block of code for each select filter works on their own, but not together.
If the filterByAlbum
in the v-for
loop refers to the puted property, which then refers back to pressEntries
data model, would it be possible to have two puted properties that the v-for
runs through (like "filterByAlbum
" and "'filterByYear`" for example)? Or do I need to figure out how to filter all the results in one massive puted property?
Since in Vue 2.0 you can no longer chain together multiple pipeline filters to a list (|filterBy
etc), how are you supposed to do this in a puted property if you have two or more select dropdowns?
I want the ability to sort by album title (from select 1) and by year (select 2).
<select v-model="albumFilter">
<option value="All">All</option>
<option value="Album 1">Album 1</option>
<option value="Album 2">Album 2</option>
<option value="Album 3">Album 3</option>
</select>
<select v-model="yearFilter">
<option value="Year">Year</option>
<option value="2017">2017</option>
<option value="2016">2016</option>
<option value="2015">2015</option>
</select>
<ul>
<li v-for="review in filterByAlbum" v-if="review.type === 'recordReview'">
<a :href="review.jsonUrl">
[[ review.title ]]
</a>
</li>
</ul>
Vue js code:
data() {
return {
pressEntries: [],
albumFilter: 'All',
yearFilter: 'Year'
}
},
filterByAlbum: function() {
// Select 1 (Album Filter)
switch (this.albumFilter) {
case 'All':
return this.pressEntries;
break;
case 'Neither':
return this.pressEntries.filter(entry => {
return entry.relatedRecording === null
});
break;
default:
return this.pressEntries.filter(entry => {
return entry.relatedRecording === this.albumFilter
});
}
// Select 2 (Year Filter)
if (this.yearFilter === 'Year') {
return this.pressEntries;
}
else {
return this.pressEntries.filter(entry => {
let postDate = new Date(entry.postDate.date);
return JSON.stringify(postDate.getFullYear()) === this.yearFilter;
});
}
}
The pressEntries
data model gets data from an API, which I didn't bother including the code for. Each block of code for each select filter works on their own, but not together.
If the filterByAlbum
in the v-for
loop refers to the puted property, which then refers back to pressEntries
data model, would it be possible to have two puted properties that the v-for
runs through (like "filterByAlbum
" and "'filterByYear`" for example)? Or do I need to figure out how to filter all the results in one massive puted property?
2 Answers
Reset to default 3Here is an example of a puted that would work. You could move albumFilter
and yearFilter
into their own methods as well. Essentially using this kind of technique, you could assemble as many filters together as you wanted.
function filterByAlbum(){
const albumFilter = entry =>
(this.albumFilter == 'All') ||
(this.albumFilter == 'Neither' && !entry.relatedRecording) ||
(entry.relatedRecording === this.albumFilter);
const yearFilter = entry =>
(this.yearFilter == 'Year') ||
(new Date(entry.postDate.date).getFullYear() == this.yearFilter);
const reducer = (accumulator, entry) => {
if (albumFilter(entry) && yearFilter(entry))
accumulator.push(entry);
return accumulator;
}
return this.pressEntries.reduce(reducer, []);
}
new Vue({
el: "#app",
data() {
return {
pressEntries,
albumFilter: 'All',
yearFilter: 'Year'
}
},
puted:{
filterByAlbum
}
})
I had to guess at your data structure, but here is a working example.
This is my solution: You can easily add a 3 Selectbox
https://codepen.io/anon/pen/PjOoEN
function() {
var vm = this;
var category = vm.selectedCategory;
var gender = vm.selectedGender;
if(category === "All" && gender === "All") {
return vm.people;
} else {
return vm.people.filter(function(person) {
return (category === 'All' || person.category === category) && (gender === 'All' || person.gender === gender);
});
}
}