Reputation: 801
I have the following computed function so filter my houses based on a search input field. This works.
computed: {
filtered: function() {
var self = this;
let searchTerm = (this.search || "").toLowerCase()
if(this.houses) {
return this.houses.filter(function(item) {
let city = (item.city || "").toLowerCase()
let street = (item.street || "").toLowerCase()
return city.indexOf(searchTerm) > -1 || street.indexOf(searchTerm) > -1;
})
}
}
}
But how to implement ordering on City and Street also? Both asc and desc.
This is the table:
<input type="search" v-model="search" placeholder="Search for City OR Street" />
<table>
<thead>
<tr>
<th @click="sortByStreet()">Street</th>
<th @click="sortByCity()">City</th>
</tr>
</thead>
<tbody>
<tr v-for="house in filtered">
<td>{{ house.street }}</td>
<td>{{ house.city }}</td>
</tr>
</tbody>
</table>
How to fix it with the functions sortByStreet()
and sortByCity()
? Combined with the filter.
Upvotes: 1
Views: 2957
Reputation: 43881
Your click
s should set a variable, call it sortBy
, that the computed uses to determine how it sorts its results. When the variable changes, the computed will recompute.
new Vue({
el: '#app',
data: {
search: 'Z-town',
reverse: false,
houses: [{
street: 'First',
city: 'Z-town'
},
{
street: 'Second',
city: 'A-town'
},
{
street: 'First',
city: 'A-town'
},
{
street: 'Second',
city: 'Z-town'
}
],
sortBy: 'street'
},
computed: {
filtered: function() {
const result = this.houses
.filter(entry => [entry.street, entry.city].find(x => x === this.search))
.sort((a, b) =>
a[this.sortBy] < b[this.sortBy] ? -1 : a[this.sortBy] !== b[this.sortBy]
);
return this.reverse ? result.reverse() : result;
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<input type="search" v-model="search" placeholder="Search for City OR Street" />
<input type="checkbox" v-model="reverse"> Descending
<table>
<thead>
<tr>
<th @click="() => sortBy = 'street'">Street</th>
<th @click="() => sortBy = 'city'">City</th>
</tr>
</thead>
<tbody>
<tr v-for="house in filtered">
<td>{{ house.street }}</td>
<td>{{ house.city }}</td>
</tr>
</tbody>
</table>
</div>
Upvotes: 3