Reputation:
Trying to sort by price and by date. the code is below. I didn't use the controller for that. is it possible to make it here?
it's "kind" of working. the problem is, when I select price it's not sorting. but when I select date it's sorting but not date price???? after that when I select price one more time then it's sort the date????? AND date is sorting by asc, how can I change it to desc :) I update the code could you please check it? Thank you for helping me out.
data() {
return {
estates: [],
keyword: '',
regions:[],
rooms:[],
sortType:''
}
},
created(){
axios.get('/ajax').then((response) => {
this.estates = response.data;
});
},
computed: {
one: function () {
let filteredStates = this.estates.filter((estate) => {
return (this.keyword.length === 0 || estate.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if(this.sortType == 'price') {
this.estates = this.estates.sort((prev, curr) => prev.price - curr.price);
}
if(this.sortType == 'created_at') {
this.estates = this.estates.sort((prev, curr) => Date.parse(prev.created_at) - Date.parse(curr.created_at));
}
return filteredStates;
}
}
}
<select v-model="sortType" v-on:change="one">
<option value="">Sort Type</option>
<option value="price">price</option>
<option value="created_at">Date</option>
</select>
Thank you for helping me out.
Upvotes: 1
Views: 2483
Reputation: 536
I think the easiest way to accomplish that would be to store the result of the first sorting in a variable filteredStates
, and then using the same variable to filter again according to the sort by date.
Code example:
computed: {
one: function () {
let filteredStates = this.estates.filter((estate) => {
return (this.keyword.length === 0 || estate.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if (this.sortBy == 'created_at') {
filteredStates = filteredStates.sort((prev, curr) => Date.parse(prev.created_at) - Date.parse(curr.created_at));
}
return filteredStates;
}
}
I'm sure there is a faster way to achieve the same result, but this way is easier to understand what is going on in the code.
Let me know if that works ; )
UPDATE:
The problem is that you are using this.estates
instead of the variable filteredStates
that has the filtered results stored on it. You have to keep using filteredStates
in all subsequent filters. Please see example:
computed: {
one: function () {
let filteredStates = this.estates.filter((estate) => {
return (this.keyword.length === 0 || estate.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if(this.sortType == 'price') {
filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
}
if(this.sortType == 'created_at') {
filteredStates = filteredStates.sort((prev, curr) => Date.parse(prev.created_at) - Date.parse(curr.created_at));
}
return filteredStates;
}
}
Upvotes: 0
Reputation: 870
Here is an example of using sort in Vue computed: https://jsfiddle.net/jxuLdhz3/
sortedItems() {
if (this.sortBy === 'by-date') {
return this.items.sort((prev, curr) => {
return new Date(prev.date) - new Date(curr.date);
});
}
if (this.sortBy === 'by-price') {
return this.items.sort((prev, curr) => {
return prev.price - curr.price;
});
}
return this.items;
},
Sort reference: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
UPD-01: If you need to sort by several fields i recommend you to use a lodash.js
https://lodash.com/docs/4.17.11#orderBy
_.orderBy(this.items, ['price', 'date'], ['asc', 'asc']);
Upvotes: 0
Reputation: 816
You can use sort
function on array.
Like:
const filtered = [
{price: 20, date: '12-12-2020'},
{price: 15, date: '23-12-2019'},
{price: 23, date: '12-12-2028'},
].sort((prev, curr) => prev.price - curr.price);
console.log(filtered)
You can pass you array on my array and return the filtered array.
prev
is previous object and curr
is current object.
What is sort
?
Its a function that provide callback function for sorting the array.
I have sorted is with the price you can try price
and date
For you code:
<select v-model="sortType" v-on:change="sortItem()">
<option value="">Sort Type</option>
<option value="price">Price</option>
<option value="created_at">Date</option>
</select>
<ul>
<li v-for="item of estates">Price: {{item.price}}, Date: {{item.created_at}}</li>
</ul>
Script:
data: () => {
return {
sortType: '',
estates: []
}
},
mounted() {
this.estates = [{
price: 20,
created_at: '2019-01-28 09:31:42'
},
{
price: 15,
created_at: '2019-01-28 09:31:42'
},
{
price: 23,
created_at: '2019-01-28 09:30:42'
},
];
},
methods: {
sortItem() {
if (this.sortType == 'price') {
this.estates = this.estates.sort((prev, curr) => prev.price - curr.price);
}
if (this.sortType == 'created_at') {
this.estates = this.estates.sort((prev, curr) => Date.parse(prev.created_at) - Date.parse(curr.created_at));
}
}
}
Upvotes: 1