Reputation: 822
I have a JSON object with nested objects that I am iterating over to pull out data. All is working fine, but I'd like to add a search/filter implementation so that the search is being done on the second level of the nested for
loop. I have it somewhat working but im not getting any data returned. Here is an example:
https://codesandbox.io/s/vue-template-s9t9o
In the HelloWorld component is where the search/filter is happening. As you can see its not outputting the rest of the data after it passes through the searchFilter method.
To make it work without the search/filter, change the following on line #6
:
from: <div class="contentSingle" v-for="(c, i) in searchFilter" :key="i">
to: <div class="contentSingle" v-for="(c, i) in cont" :key="i">
Anyone can think of what I can do to make this work? I need to filter by the elements inside each of the content
inside the main data object. You can find the data object inside the FauxData/dataContent.js
dir.
Thanks a lot.
-S
Upvotes: 0
Views: 1438
Reputation: 22403
You should use methods instead of computed:
methods: {
filterValue(content) {
return content.filter(item => {
let itemUpper = item.content.toUpperCase();
let searchUpper = this.search.toUpperCase();
return itemUpper.indexOf(searchUpper) > -1;
});
}
}
and then in HTML code:
<section id="content">
<input type="text" id="search" name="search" v-model="search" placeholder="Search Content...">
<div v-for="(cont, index) in content" :key="index" class="contentWrapper">
<h1>{{ index }}</h1>
<div class="contentSingle" v-for="(c, i) in filterValue(cont)" :key="i">
<h3>{{ c.title }}</h3>
<div v-html="c.content"></div>
</div>
</div>
</section>
Updated
If you want to hide the empty section, then use computed value:
computed: {
filteredData() {
return Object.keys(this.content).reduce((a, cKey) => {
const data = this.filterValue(this.content[cKey]);
if (data.length) {
a[cKey] = data;
}
return a;
}, {});
}
},
methods: {
filterValue(content) {
return content.filter(item => {
let itemUpper = item.content.toUpperCase();
let searchUpper = this.search.toUpperCase();
return itemUpper.indexOf(searchUpper) > -1;
});
}
}
Use filteredData
in outer v-for
<section id="content">
<input type="text" id="search" name="search" v-model="search" placeholder="Search Content...">
<div v-for="(cont, index) in filteredData" :key="index" class="contentWrapper">
<h1>{{ index }}</h1>
<div class="contentSingle" v-for="(c, i) in cont" :key="i">
<h3>{{ c.title }}</h3>
<div v-html="c.content"></div>
</div>
</div>
</section>
Demo on codepen
Upvotes: 2