In order to achieve for multi search function we add a search field at each header with v-slot where we define the header name directly. For example:
<template v-slot:header.NAME="{ header }">
{{ header.text }}
<v-menu offset-y :close-on-content-click="false">
<template v-slot:activator="{ on, attrs }">
<v-text-field v-bind="attrs" v-on="on"
v-model="nameSearch"
class="pa"
type="text"
></v-text-field>
</template>
</v-menu>
</template>
Now I have around 50 headers for my data table. My idea is to render dynamically. I tried with v-for but neither it renders and or give any error. Code below:
<template v-for="(x, index) in this.headers" slot="headers" slot-scope="props">
{{ props.x.text }}
<v-menu offset-y :close-on-content-click="false" :key="index">
<template v-slot:activator="{ on, attrs }">
<v-text-field v-bind="attrs" v-on="on"
v-model="searchObj"
class="pa"
type="text"
></v-text-field>
</template>
</v-menu>
</template>
what did i missed here ? or it is completely wrong way i went ?
Below is the full code:
<template>
<v-app class="main-frame">
<v-main>
<v-data-table
:headers="headers"
:items="filteredData"
>
<template v-slot:header.NAME="{ header }">
{{ header.text }}
<v-menu offset-y :close-on-content-click="false">
<template v-slot:activator="{ on, attrs }">
<v-text-field v-bind="attrs" v-on="on"
v-model="nameSearch"
class="pa"
type="text"
></v-text-field>
</template>
</v-menu>
</template>
<template v-slot:header.DEPARTMENT="{ header }">
{{ header.text }}
<v-menu offset-y :close-on-content-click="false">
<template v-slot:activator="{ on, attrs }">
<v-text-field v-bind="attrs" v-on="on"
v-model="departmentSearch"
class="pa"
type="text"
></v-text-field>
</template>
</v-menu>
</template>
</v-data-table>
</v-main>
</v-app>
</template>
<script>
import axios from "axios";
}
export default {
name: 'Home',
data() {
return {
/* Table data */
headers: []
allData: [],
/* Column Search */
nameSearch: '',
departmentSearch: ''
}
},
computed: {
filteredData() {
let conditions = [];
if (this.nameSearch) {
conditions.push(this.filterName);
}
if (this.departmentSearch) {
conditions.push(this.filterDepartment);
}
if (conditions.length > 0) {
return this.allData.filter((data) => {
return conditions.every((condition) => {
return condition(data);
})
})
}
return this.allData;
}
},
mounted () {
this.getAllData()
},
methods: {
getAllData() {
this.allData = []
axios
.get("http://localhost:5001/"}
.then(res => {
if (res.status === 200) {
if (res.data === 0) {
console.log("Something is wrong !!!")
} else {
this.allData = res.data["allData"]
this.headers = res.data["allDataHeaders"]
}
}
}).catch(error => {
console.log(error);
})
},
filterName(item) {
return item.NAME.toLowerCase().includes(this.nameSearch.toLowerCase())
},
filterDepartment(item) {
return item.DEPARTMENT.toLowerCase().includes(this.departmentSearch.toLowerCase())
},
}
}
</script>
I have found the solution myself:
<template v-for="(header, i) in headers" v-slot:
[`header.${header.value}`]="{ }">
<div @click.stop :key="i">
{{ header.text }}
<v-text-field :key="i"
v-model="multiSearch[header.value]"
class="pa"
type="text"
:placeholder="header.value"
prepend-inner-icon="mdi-magnify"
></v-text-field>
</div>
</template>
In data, I have an empty object called:
searchObj: {}
and in computed method, i have the following method:
filteredData() {
if (this.searchObj) {
return this.allData.filter(item => {
return Object.entries(this.searchObj).every(([key, value]) => {
return (item[key] || '').toLowerCase().includes(value.toLowerCase())
})
})
} else {
return this.allData
}
},
Full solution below:
<template>
<v-app class="main-frame">
<v-main>
<v-data-table
:headers="headers"
:items="filteredData"
>
<template v-for="(header, i) in headers" v-slot:
[`header.${header.value}`]="{ }">
{{ header.text }}
<div @click.stop :key="i">
<v-text-field :key="i"
v-model="multiSearch[header.value]"
class="pa"
type="text"
:placeholder="header.value"
prepend-inner-icon="mdi-magnify"
></v-text-field>
</div>
</template>
</v-data-table>
</v-main>
</v-app>
</template>
<script>
import axios from "axios";
}
export default {
name: 'Home',
data() {
return {
/* Table data */
headers: []
allData: [],
searchObj: {},
}
},
computed: {
filteredData() {
if (this.searchObj) {
return this.allData.filter(item => {
return Object.entries(this.searchObj).every(([key, value]) => {
return (item[key] ||'').toLowerCase().includes(value.toLowerCase())
})
})
} else {
return this.allData
}
},
},
mounted () {
this.getAllData()
},
methods: {
getAllData() {
this.allData = []
axios
.get("http://localhost:5001/"}
.then(res => {
if (res.status === 200) {
if (res.data === 0) {
console.log("Something is wrong !!!")
} else {
this.allData = res.data["allData"]
this.headers = res.data["allDataHeaders"]
}
}
}).catch(error => {
console.log(error);
})
},
}
}
</script>