I have a data coming from API. It is an array of "houses".
Code looks like this:
<template>
<div class="search__sort">
<input v-model="search" placeholder="Search for a house">
<button class="sort__button">Price</button>
<button class="sort__button">Size</button>
</div>
<div v-for="house in houses" :key="house.id" class="house">
<router-link :to="{ name: 'HouseDetails', params: { id: house.id}}" >
<h2>ID = {{ house }}</h2>
<h3> {{ house.location.street}} </h3>
<img :src="house.image" />
</router-link>
<button v-if="house.madeByMe" class="delete" @click="deleteHouse(house.id)">Delete</button>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Houses',
data(){
return {
houses: [],
}
},
created() {
this.getHouses();
},
methods: {
getHouses(){
// GET request using axios with set headers
const headers = { "CENSORED": "CENSORED" };
axios.get('myAPI', { headers })
.then(response => this.houses = response.data);
},
deleteHouse(id) {
const headers = { "CENSORED": "CENSORED" };
axios.delete('myAPI' id, { headers })
.then(response => {
console.log(response);
})
.catch(function (error) {
console.log(error.response);
});
},
},
}
</script>
I somehow need to implement the filter by text input, so that for example, if user types a city name it will show all of those houses or a street name to filter that by street.
Any suggestions how I can do that with code that I already have?
CodePudding user response:
You can use computed
property:
new Vue({
el: '#demo',
data() {
return {
search: '',
houses: [{ "id": 2, "image": "myAPI/house1.jpg", "price": 123, "rooms": { "bedrooms": 1, "bathrooms": 1 }, "size": 500, "description": "oui", "location": { "street": "street 20", "city": "assas", "zip": "asasdd" }, "createdAt": "2020-05-07", "constructionYear": 2000, "hasGarage": false, "madeByMe": false }, { "id": 3, "image": "myAPI/house1.jpg", "price": 123, "rooms": { "bedrooms": 1, "bathrooms": 1 }, "size": 500, "description": "oui", "location": { "street": "street 20", "city": "adb", "zip": "asasdd" }, "createdAt": "2020-05-07", "constructionYear": 2000, "hasGarage": false, "madeByMe": false },{ "id": 4, "image": "myAPI/house1.jpg", "price": 123, "rooms": { "bedrooms": 1, "bathrooms": 1 }, "size": 500, "description": "oui", "location": { "street": "street 20", "city": "bbb", "zip": "asasdd" }, "createdAt": "2020-05-07", "constructionYear": 2000, "hasGarage": false, "madeByMe": false }],
}
},
computed: {
filteredHouses(){
return this.houses.filter(h => h.location.city.toLowerCase().includes(this.search.toLowerCase()))
}
}
})
Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div class="search__sort">
<input v-model="search" placeholder="Search for a house">
<button class="sort__button">Price</button>
<button class="sort__button">Size</button>
</div>
<div v-for="house in filteredHouses" :key="house.id" class="house">
<h3> {{ house.location.city}} </h3>
<img :src="house.image" />
</div>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You will want to distinguish the difference between
houses
anddisplayedHouses
such that,displayedHouses
is your filtered array.<h2>ID = {{ house }}</h2>
is not going to play well with your testingdisplayedHouses
will be acomputed
looking something like:
computed:
{
/**
* @return {array} List of displayed houses from search input
*/
displayedHouses()
{
if (!this.houses || !this.houses.length)
{
return []
}
if (!this.search)
{
return this.houses
}
return this.houses.filter( (house) =>
{
return house.city.includes(this.search) || house.state.includes(this.search) // || whatever else you want
})
}
},