Categories
checkbox javascript vue-component vue.js vuejs2

Check / Uncheck a Checkbox in a child component with vuejs

Context :

I am using VueJS in a project for the first time so I’m potentially not using it the right way.

I have a parent and a child component :

Parent : ResearchProducts.vue : Displays a list of products that can be filtred by their categories. The filters are checkboxes related to the category of the products.

Child : CategoryDisplay.vue : This is the component that handle the view and the methods of a category row.

My Question :

When I click on a category checkbox inside of my child component and if the checkbox is checked, the category is added to a list of filters in the parent. This works.

When I uncheck the checkbox, the category is removed from this list. This works too.

Now I’ve showed all my categories as buttons in the parent component to make the filters visible more easily for the user. And my problem is that I want this button to uncheck the related checkbox inside the child component when I click on it.

Here is my actual code :

ResearchProducts.vue :

<template>
<div>
<template v-for="category in categories">
<category-display
:category="category"
:key="'category_'+category.id"
:checked="checked"
@categorySelected="categorySelected"
></category-display>
</template>
<button
v-for="filter in listFilters"
:key="'filter_'+filter.slug"
class="btn btn-light btn-sm mr-2 mb-2"
@click="removeFilter(filter)"
>
{{ filter.name }}
</button>
</div>
</template>
<script>
export default {
data() {
return {
categories: { // HERE A COLLECTION CONTAINING ALL MY CATEGORIES },
selectedCategories: [],
listFilters: []
};
},
methods: {
categorySelected(category) {
var newCategory = {
type: "category",
slug: category.slug,
name: category.name
};
if (category.checked) {
if (!this.selectedCategories.includes(category.slug)) {
this.selectedCategories.push(category.slug);
this.listFilters.push(newCategory);
}
} else {
if (this.selectedCategories.includes(category.slug)) {
const index = this.selectedCategories.indexOf(category.slug);
if (index > -1) {
this.selectedCategories.splice(index, 1);
}
}
this.listFilters = this.listFilters.filter(function(item) {
for (var key in newCategory) {
if (item[key] === undefined || item[key] == newCategory[key])
return false;
}
return true;
});
}
},
removeFilter(filter) {
// THERE, I NEED TO UNCHECK THE RELATED CHECKBOX IN CHILD COMPONENT
this.listFilters = this.listFilters.filter(function(item) {
for (var key in filter) {
if (item[key] === undefined || item[key] == filter[key]) return false;
}
return true;
});
}
}
};
</script>

CategoryDisplay.vue :

<template>
<b-form-checkbox-group class="w-100">
<b-form-checkbox :value="category.slug" class="w-100" @input="selection" v-model="selected" ref="checked">
{{ category.name }}
<span class="badge badge-secondary float-right">{{ category.products_count }}</span>
</b-form-checkbox>
</b-form-checkbox-group>
</template>
<script>
export default {
props: {
category: {
type: Object,
required: true
}
},
data() {
return {
selected: false
}
},
methods: {
selection() {
var response = false;
if(this.selected.length !== 0){
response = true;
}
this.$emit('categorySelected', {slug: this.category.slug, name: this.category.name, checked: response});
}
}
};
</script>