I am currently new to Vue.js and this is my first question on stack so forgive me if I am not the most clear.
I am trying to create multiple dynamic select filters to filter a list that I have gotten from an api using axios.
I have surfaced the data within my HTML template and have managed to create the two filters, my main issue is that I need the filters to only display unique values (no duplicates) and this is where I am struggling.
This is mainly a proof of concept for work which displays a group of users names, there label and position. We where using angularjs before and are now looking to move over to Vue.js, so I haven't gotten to grips with it yet, and currently stumped as I don't understand how to make the information from one source data array filter another source data array.
Here is what I have currently in my app.js
new Vue({
el: "#vueApp",
data: {
users: [],
JobRole: '',
Label: '',
search: '',
JobRoles: [],
},
created: function() {
this.getResults();
},
methods: {
getResults: function() {
var vm = this;
axios.get("APIData").then(function(response) {
console.log(response.data.value);
vm.users = response.data.value;
})
},
filterPosition:function() {
var vm = this;
vm.item.Position = event.target.value;
},
filterLabel:function() {
var vm = this;
vm.item.Meta.Label = event.target.value;
}
},
computed: {
JobRoleList: function(){
var vm = this;
var JobRoles = [];
vm.users.forEach(function(item){
if(!JobRoles.includes(item.Position)){
JobRoles.push(item.Position);
console.log(JobRoles);
}
});
return JobRoles;
},
filterAll: function(){
var vm = this;
var filtered = vm.users;
// var JobRoles = vm.JobRoles;
if (vm.search) {
filtered = vm.users.filter(function(item){
return item.People.Title.indexOf(vm.search) > -1
});
}
if (vm.Label) {
filtered = filtered.filter(function(item){
return item.Meta.Label.match(vm.Label)
});
}
if (vm.JobRole) {
vm.JobRole = filtered.filter(function(item){
return item.Position.match(vm.JobRole)
console.log(JobRole);
});
}
return filtered
console.log(filtered);
},
}
});
Here is my Markup
<div id="vueApp">
<div>
<select v-model="JobRole">
<option value="">Select a Position</option>
<option v-for="item in JobRoleList" :value="item.Position">{{item}}</option>
</select>
<select v-model="Label">
<option value="">Select a Label</option>
<option v-for="item in filterAll" :value="item.Meta.Label">{{item.Meta.Label}}</option>
</select>
<input type="text" v-model="search" placeholder="Search...">
<table>
<tr>
<th>Name</th>
<th>Department</th>
<th>Position</th>
<!-- <th>People Title</th> -->
</tr>
<tr v-for="item in filterAll">
<td>{{item.People.Title}}</td>
<td>{{item.Meta.Label}}</td>
<td>{{item.Position}}</td>
</tr>
</table>
</div>
</div>
So what I want to get to is have each filter to have unique values with no duplication and to filter the information within the list.
I have managed to create a unique value array for one of the select filters under JobRoleList, I just need to know how to have it communicate with the filterAll array, if I can get to that stage then all I would need to do is replicate that for the other filter.
I would appreciate any help and would be more than happy to provide more detail.
There are a few problems with your code:
:value="item.Position"
when the JobRoleList
variable is an array of strings. So when you click select there won't be a value for JobRole
<select v-model="JobRole">
<option value="">Select a Position</option>
<option v-for="item in JobRoleList" :value="item.Position">{{item}}</option>
</select>
filterAll
computed variable in the jobRole
part if (vm.JobRole) {
vm.JobRole = filtered.filter(function(item){
return item.Position.match(vm.JobRole)
console.log(JobRole);
});
// This should say "filtered =" not "vm.JobRole ="
}
There's also a much more succinct way to get a unique list of values using ES6:
JobRoleList: function({ users }) {
return [...new Set(users.map(d => d.Position))];
}
You can also make your search all lower case letters before matching to improve the user experience.
filtered = users.filter(function(item){
return item.People.Title.toLowerCase().indexOf(search.toLowerCase()) > -1
});
I've made a codepen with a working demo: https://codepen.io/CodingDeer/pen/abomBXP
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.