<li v-for="(option, option_index) in filter.options" :key="option_index" class="flex justify-between py-1 text-sm">
<label>
- <input type="checkbox" v-model="filters[filter.id]" :value="option.value">
+ <input type="checkbox" v-model="filters[filter.id]" :value="option.value" @change="updateFilters">
{{ option.label }}
</label>
<div class="products-grid flex-grow">
<!-- Grid summary header -->
- <div class="products-grid-summary sticky top-0 z-10 bg-grey-100 pt-4 pb-4 flex justify-between items-center md:block">
+ <div class="products-grid-summary sticky top-0 z-10 bg-grey-100 pt-4 pb-4 flex justify-between md:block">
<!-- Active filters -->
<div class="products-grid-active-filters flex-grow text-sm">
<ul class="flex flex-wrap -mb-3 md:mb-0">
<template v-for="(filter, filterID) in filters">
- <li class="bg-white whitespace-no-wrap py-2 px-4 rounded-full mr-3 mb-3 hover:bg-grey-200 cursor-pointer"
+ <li class="bg-white whitespace-no-wrap py-2 px-4 rounded-full mr-3 mb-3 hover:bg-grey-200"
v-for="filter_option in filter" v-if="filterData[filterID].options">
{{ filterData[filterID].options[filter_option].label }}
- <!-- TODO: <img src="{{ asset('images/icon-close.svg') }}" alt="Remove" class="inline-block ml-3"> -->
+ <svg class="svg inline-block ml-3 cursor-pointer" @click="removeFilter(filterID, filter_option)"
+ xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 11 11">
+ <path fill="#6B7287" d="M11 1.4L9.6 0 5.5 4.1 1.4 0 0 1.4l4.1 4.1L0 9.6 1.4 11l4.1-4.1L9.6 11 11 9.6 6.9 5.5z"/>
+ </svg>
</li>
</template>
</ul>
-
- <div class="text-red mt-4">
- QUERYSTRING: {{ filter_querystring }}
- </div>
-
</div>
<!-- Total Results -->
<div class="products-grid-result-count pl-4 md:pl-0 font-display whitespace-no-wrap">
- <!-- TODO: handle count and translations
- {{ count($products) }}
- @if(count($products) == 1)
- {{ __('résultat') }}
- @else
- {{ __('résultats') }}
- @endif
- -->
+ {{ resultsCount }}
</div>
</div>
export default {
props: {
+ productType: {
+ required: true,
+ },
filterData: {
required: true,
},
resultData: {
required: true,
},
+ translations: {
+ type: Object,
+ required: true,
+ }
},
data: () => ({
filters: {},
}),
computed: {
- filter_querystring() {
+
+ resultsCount() {
+ let count = Object.keys(this.matches.hits).length;
+ let results = '';
+
+ // Handle pluralisation and localisation
+ if (count === 1) {
+ results = this.translations.result;
+ } else {
+ results = this.translations.results;
+ }
+
+ return `${count} ${results}`;
+ },
+
+ filterQuerystring() {
let filter_list = [];
},
},
- mounted() {
+ created() {
// Initially, it will be all the IDs from the server
this.matches = this.resultData;
methods: {
+ updateFilters() {
+ let $this = this;
+ let endpoint = `/ajax/filtercatalog/?productType=${this.productType}&${this.filterQuerystring}`;
+
+ axios.get(endpoint)
+ .then(function (response) {
+ $this.matches = response.data.results;
+ $this.filterProducts();
+ })
+ .catch(function (error) {
+ console.error('Error filtering products', error);
+ });
+ },
+
+ filterProducts() {
+ let matches = Object.values(this.matches.hits);
+
+ this.$slots.default[0].children.forEach(child => {
+ if (child.tag) { // Ensure it's a tag and not an empty text element
+ let product = child.elm;
+ let ID = parseInt(product.dataset.productId);
+ if (matches.includes(ID)) {
+ product.classList.remove('hidden');
+ } else {
+ product.classList.add('hidden');
+ }
+ }
+ });
+ },
+
+ removeFilter(filterID, optionID) {
+ let index = this.filters[filterID].indexOf(optionID);
+
+ if (index !== -1) {
+ this.filters[filterID].splice(index, 1);
+ this.updateFilters();
+ }
+ },
},
}