Reputation: 193
I want to search with vue js, normal search works fine, but if we consider that there are 1000 records in the list, and when the user wants to search by filtering, what kind of action can I apply? I couldn't understand if there is a plugin for this, I searched and couldn't find it. I have drawn such a way, thinking that for example, users with "status blocked" and "close" want to be listed in the filtering, and if they want to search from the incoming list accordingly, I have drawn such a way, but as I said, I am new to vuejs and if you can show it as an example. Thank you from now.
const app = new Vue({
el: '#app',
data: {
search: '',
userList: [
{
id: 1,
name: "Prem",
age: 18,
status: "close",
gender: "male",
},
{
id: 2,
name: "Chandu",
status: "close",
age: 20,
gender: "female",
},
{
id: 3,
name: "Shravya",
status: "open",
age: 35,
gender: "female",
},
{
id: 4,
name: "Shravya",
status: "blocked",
age: 35,
gender: "female",
}
]
},
computed: {
filteredAndSorted() {
function compare(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
return this.userList.filter(user => {
return user.name.toLowerCase().includes(this.search.toLowerCase())
}).sort(compare)
}
}
});
$(document).ready(function () {
$('.dropdown-submenu a.test').on("click", function (e) {
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
.dropdown-submenu {
position: relative;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">Filtered
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">Name</a></li>
<li><a tabindex="-1" href="#">Age</a></li>
<li><a tabindex="-1" href="#">Gender</a></li>
<li class="dropdown-submenu">
<a class="test" tabindex="-1" href="#">Status <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>
<input type="checkbox" value="close">
<button>Close</button>
</li>
<li>
<input type="checkbox" value="open">
<button>Open</button>
</li>
<li>
<input type="checkbox" value="blocked">
<button>Blocked</button>
</li>
</ul>
</li>
</ul>
</div>
<div class="search-wrapper">
<input type="text" v-model="search" placeholder="Search title.."/>
</div>
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>Status</th>
<th>Gender</th>
</tr>
<tr v-for="user in filteredAndSorted">
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
<td>{{ user.status }}</td>
<td>{{ user.gender }}</td>
</tr>
</table>
</div>
Upvotes: 3
Views: 239
Reputation: 23480
I made you a snippet, take a look (no need for jquery):
const app = new Vue({
el: '#app',
data: {
search: '',
selected: 'name',
choice: '',
choicesArr: [],
options: [
{ text: 'Name', value: 'name' },
{ text: 'Age', value: 'age' },
{ text: 'Gender', value: 'gender' },
{ text: 'Status', value: 'status' }
],
userList: [
{
id: 1,
name: "Prem",
age: 18,
status: "close",
gender: "male",
},
{
id: 2,
name: "Chandu",
status: "close",
age: 20,
gender: "female",
},
{
id: 3,
name: "Shravya",
status: "open",
age: 35,
gender: "female",
},
{
id: 4,
name: "Shravya",
status: "blocked",
age: 35,
gender: "female",
}
]
},
computed: {
filteredAndSorted() {
function compare(a, b) {
if (a[this.selected] < b[this.selected]) return -1;
if (a[this.selected] > b[this.selected]) return 1;
return 0;
}
return this.userList.filter(user => {
if (this.selected === "age") {
if(this.choicesArr.length) {
return this.choicesArr.indexOf(user[this.selected]) >= 0
} else {
return !this.search || user[this.selected] === Number(this.search)
}
} else {
if(this.choicesArr.length) {
return this.choicesArr.indexOf(user[this.selected]) >= 0
} else {
return user[this.selected].toLowerCase().includes(this.search.toLowerCase())
}
}
}).sort(compare)
},
choices: function() {
return [...new Set(this.userList.map(user => user[this.selected]))];
}
},
methods: {
addChoice() {
this.choicesArr.push(this.choice)
console.log(this.choicesArr)
},
reset() {
this.choice = ""
this.choicesArr = []
}
}
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
.dropdown-submenu {
position: relative;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
<select v-model="selected" >
<option value="" disabled>Select option</option>
<option v-for="option in options" v-bind:value="option.value" >
{{ option.text }}
</option>
</select>
<select v-model="choicesArr" multiple>
<option v-for="option in choices" v-bind:value="option" @click="addChoice">
{{ option }}
</option>
</select>
<button @click="reset">Clear filters</button>
<div class="search-wrapper">
<input type="text" v-model="search" placeholder="Search title.."/>
</div>
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>Status</th>
<th>Gender</th>
</tr>
<tr v-for="user in filteredAndSorted">
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
<td>{{ user.status }}</td>
<td>{{ user.gender }}</td>
</tr>
</table>
</div>
Upvotes: 2