I am new to vuejs. I have this table:
<table>
<thead>
<tr
v-for="(items, index) in data"
v-if="index == 0">
<td v-for="(item, key) in items">
{{ key }}
</td>
</tr>
</thead>
<tbody>
<tr v-for="(items, index) in filteredData">
<td v-for="item in items">
{{ item }}
</td>
</tr>
</tbody>
</table>
I want to filter the rows and display the ones that matches whatever is in this input:
<input
type="text"
placeholder="Search something..."
v-model="searchQuery">
I have successfully done this with a computed property.
computed: {
filteredData: function() {
return this.data.filter((items) => {
for (var item in items) {
if(String(items[item]).indexOf(this.searchQuery) !== -1) {
return true
}
}
return false
})
}
},
This filters the table and displays only the rows that have a cell that matches whatever is in the input. This works perfectly.
However, now I want to filter and show only the rows whose cells match what is in the input but only search through a column chosen from a select tag, which I have created below:
<select
id="columnsSelect"
v-model="selected">
<option
v-for="column in columns"
:value="column">
{{ column }}
</option>
</select>
I hope I am making sense. I do not know how to proceed from here. Cookies and a big thank you to anyone who helps!
You're on the right track with filtering using a computed property, now you just need to add the logic to filter the rows based on the selected column. For example:
new Vue({
el: '#app',
data: () => ({
search: null,
column: null,
items: []
}),
beforeMount () {
this.items = Array.from(Array(20), (x,i) => {
return {
id: i,
name: Math.random().toString(36).substring(7),
title: Math.random().toString(36).substring(7),
description: Math.random().toString(36).substring(7)
}
})
},
computed: {
cols () {
return this.items.length >= 1 ? Object.keys(this.items[0]) : []
},
rows () {
if (!this.items.length) {
return []
}
return this.items.filter(item => {
let props = (this.search && this.column) ? [item[this.column]] : Object.values(item)
return props.some(prop => !this.search || ((typeof prop === 'string') ? prop.includes(this.search) : prop.toString(10).includes(this.search)))
})
}
}
})
* {
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
#app {
width: 20rem;
}
#app > div {
display: flex;
flex-direction: row;
}
select, input {
width: 50%;
}
table {
width: 100%;
border: 1px solid black;
text-align: center;
border-spacing: 0;
}
td {
border-top: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<select v-model="column">
<option :value="null">No Column Filter</option>
<option v-for="col in cols" :key="col">{{ col }}</option>
</select>
<input type="text" v-model="search" placeholder="Search">
</div>
<table>
<thead>
<tr>
<th v-for="col in cols" :key="col">{{ col }}</th>
</tr>
</thead>
<tbody>
<tr v-for="row in rows" :key="row.id">
<td v-for="col in cols" :key="col">{{ row[col] }}</td>
</tr>
</tbody>
</table>
</div>
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