I have a Tagging Tool Component with 3 different levels of priority. Now I would like to a filter search. Is it possible to access tags[n] in the computed tagsFilter function?
This my current version: https://jsfiddle.net/hej7L1jy/26/
I would like to replace v-for="tag in tags[n]" with: v-for="tag in tagsFilter"
In the moment I receive a TypeError: this.tags.filter is not a function
Does anyone have an idea?
Vue.js Template:
<div id="app">
<input id="input-search" type="text" class="form-inline pull-right" v-model="textSearch" placeholder='Search...'>
<div v-for="n in prios">
<h3>{{n}} tag priority</h3>
<ul v-if="tagsFilter && tagsFilter.length">
<li :class="'tagPriority-'+n" v-for="tag in tagsFilter">
<label class="checkbox-inline"><input name="tags[]" type="checkbox" v-model="tagSelected" :value="tag.id"> {{tag.title}}</label>
</li>
</ul>
</div>
</div>
Vue.js component:
new Vue({
el: '#app',
props: {
selectedTags: {
type: Array
}
},
data() {
return {
prios: [ 1, 2, 3 ],
tagSelected: [],
tags: [],
textSearch: ''
}
},
computed: {
tagsFilter: function() {
var textSearch = this.textSearch;
return this.tags.filter(function(el) {
return el.title.toLowerCase().indexOf(textSearch.toLowerCase()) !== -1;
});
}
},
created: function () {
this.tagSelected = this.selectedTags;
this.tags = {"1":[{"id":9,"title":"Auto"}],"2":[{"id":8,"title":"Elektroauto"}],"3":[{"id":10,"title":"BMW i3"},{"id":11,"title":"Opel Ampera"},{"id":12,"title":"Renault TWIZY"}]};
}
});
Although you define tags in your data:
data() {
return {
tags: [],
}
},
Your created callback overrides this.tags:
created: function () {
this.tagSelected = this.selectedTags;
this.tags = {"1":[{"id":9,"title":"Auto"}],"2":[{"id":8,"title":"Elektroauto"}],"3":[{"id":10,"title":"BMW i3"},{"id":11,"title":"Opel Ampera"},{"id":12,"title":"Renault TWIZY"}]};
}
Turning it into an object, which has no filter method.
Your template:
<li :class="'tagPriority-'+n" v-for="tag in tags[0]">
Becomes
<li :class="'tagPriority-'+n" v-for="tag in tagsFilter[n]">
And
computed: {
tagsFilter: function() {
var textSearch = this.textSearch;
return this.tags.filter(function(el) {
return el.title.toLowerCase().indexOf(textSearch.toLowerCase()) !== -1;
});
}
},
Becomes:
computed: {
tagsFilter: function() {
var textSearch = this.textSearch;
var filteredTags = {};
var tags = this.tags;
Object.keys(this.tags).forEach(function(key) {
filteredTags[key] = tags[key].filter(function(el) {
return el.title.toLowerCase().indexOf(textSearch.toLowerCase()) !== -1;
});
});
return filteredTags;
},
},
Basically, we are iterating each of this.tags properties and adding a filtered version of each of them to filteredTags.
Demo JSFiddle here.
Another way (least amount of changed code) is to change your computed into a method with an argument:
<li :class="'tagPriority-'+n" v-for="tag in tags[0]">
Becomes
<li :class="'tagPriority-'+n" v-for="tag in tagsFilter(n)">
And
computed: {
tagsFilter: function() {
var textSearch = this.textSearch;
return this.tags.filter(function(el) {
return el.title.toLowerCase().indexOf(textSearch.toLowerCase()) !== -1;
});
}
},
Becomes:
methods: {
tagsFilter: function(i) {
var textSearch = this.textSearch;
return this.tags[i].filter(function(el) {
return el.title.toLowerCase().indexOf(textSearch.toLowerCase()) !== -1;
});
},
},
Demo JSFiddle here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With