0

I'm starting with Vue and I was reading some questions like this one to filter with computed().

I think I'm on the right path to solve my problem but I could not make it work yet.

I have a search field in my webpage to search for users according to their city. Each user have an array of filters set to true or false.

The listing process works fine. Now I want to click on filter buttons and keep in the list only users that have the clicked filter in their filters array.

html:

<div class="filters-div">
    <label class="btn btn-circle border filters-btn">
        <input type="checkbox" name="vehicle" id="vehicle" value="vehicle" v-model="checkedFilters" />
        <i></i>
        <span>Vehicle</span>
    </label>
    <label class="btn btn-circle border filters-btn">
        <input type="checkbox" name="host" id="host" value="host" v-model="checkedFilters" />
        <i></i>
        <span>Hosting</span>
    </label>
    <label class="btn btn-circle border filters-btn">
        <input type="checkbox" name="transfer" id="transfer" value="transfer" v-model="checkedFilters" />
        <i></i>
        <span>Transfer</span>
    </label>
    <label class="btn btn-circle border filters-btn">
        <input type="checkbox" name="activities" id="activities" value="activities" v-model="checkedFilters" />
        <i></i>
        <span>Night Activities</span>
    </label>
    <label class="btn btn-circle border filters-btn">
        <input type="checkbox" name="adventures" id="adventures" value="adventures" v-model="checkedFilters" />
        <i></i>
        <span>Adventures</span>
    </label>
    <label class="btn btn-circle border filters-btn">
        <input type="checkbox" name="tour" id="tour" value="tour" v-model="checkedFilters" />
        <i></i>
        <span>Tours</span>
    </label>
</div>

<div v-for="(item, index) in filterHoster" v-bind:key="item.id" class="col-md-6 mb-50">
    <div class="result-container">
        <div class="result-content2">
            <div class="result-profile-pic-div2">
                <div class="result-profile-pic2 img-fluid" v-bind:style="{'background-image': 'url(http://localhost/users/'+item.profileIMG + ')' }"></div>
            </div>
            <div class="result-profile-infos-div2">
                <div class="result-name">
                    <h4 class="mb-0">{{ item.name }} {{ item.lastname }}</h4>
                </div>
                <div class="result-rating">
                    <div class="rate-area">
                        <star-rating @rating-selected="setRating(item.id, item.rating)" :rating="item.rating"></star-rating>
                    </div>
                    <div>
                        <p>{{ item.city }} - {{ item.state }}</p>
                    </div>
                </div>
                <hr />
                <div class="tour-options">
                    <div class="tour-options-select">
                        <select :id="'select-suggestions' + item.id" name="tour-options-dropdown" v-model="selected[item.id]" class="tour-options-dropdown" @change="showTour = selected, setTour($event)">
                            <option :value="null">Tour suggestions</option>
                            <option v-for="(tour, key) in item.tours" :key="key" :value="tour.tourID">
                                {{ tour.title }}
                            </option>
                        </select>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

vue

let app = new Vue({
    el: "#app",
    data: {
        hosters: {},
        filters: {
            vehicle: "true",
            host: "true",
            transfer: "true",
            activities: "true",
            adventures: "true",
            tour: "true",
        },
        checkedFilters: [],
    },
    computed: {
        filterHoster() {
            if (!this.checkedFilters.length) return this.hosters;

            // return this.hosters.filter(f => this.checkedFilters.includes(f.filter));

            return this.hosters.filter((f) => {
                f.filters.filter((j) => {
                    this.checkedFilters.includes(j);
                });
            });
        },
    },
});

This is my database response:

enter image description here

2 Answers 2

0

if you convert hosters to array you are good to go in my case. Because filter will not work in objects.

hosters: [],

You can check it here: https://codepen.io/hasip-timurtas/pen/QWNoNjE

Sign up to request clarification or add additional context in comments.

3 Comments

Hi. unfortunately it didn't work. If I put {{ filterHoster }} in DOM to display results it get empty like before.
check {{ checkedFilters }} in DOM
It displays the input value. I tried using :value="filter.vehicle" but it throws an error. "cannot ... id of undefined" and I can't find where is this.
0

I had to make some changes in my filters response:

filters: ["vehicle", "host", "transfer", "activities", "adventures", "tour"];

and filters in data() are not being used anymore.

The final computed() is:

computed: {
    filterHoster() {
        if (!this.checkedFilters.length) return this.hosters;

        return this.hosters.filter(hoster => {
            return this.checkedFilters.some(
                filter => hoster.filters.includes(filter)
            );
        });
    }
},

This way I can check if every checked filter is included in user filters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.