Reputation: 63
I am trying to make a form which contains an input group section, in this group, there are one select box and multiple checkboxes. Checkboxes are populated based on the select box selection. There is also an add and remove button to generate and remove input group. The select box is used with v-model to filtered the checkboxes. But when I generate a new input group and make changes, all checkboxes are changed. I want them to be isolated. How can I achieve?
Here is my Template.
<template>
<form @submit.prevent="onSubmit">
<div v-for="(variationProduct, index) in variationProducts" :key="variationProduct.id">
<div class="from-group mb-4">
<label class="col-form-label"><b>Categories :</b></label>
<select class="form-control mr-2" ref="categories" v-model="category">
<option value="0">Please select category...</option>
<option v-for="category in categories" :key="category.id" :value="category.id">
{{ category.name }}
</option>
</select>
<div v-if="hasError">
<validation-errors v-if="errors['categories.'+index]" :errors="errors">
{{ errors['categories.'+index][0] }}
</validation-errors>
</div>
</div>
<div class="form-group mb-4">
<label class="col-form-lablel"><b>Variation Products :</b></label>
<div class="row">
<div v-for="filteredVariationProduct in filteredVariationProducts" :key="filteredVariationProduct.id">
<div class="col-12">
<input :id="filteredVariationProduct.id" :value="filteredVariationProduct.id" type="checkbox" ref="variationProducts">
<label :for="filteredVariationProduct.id">{{ filteredVariationProduct.name }}</label>
</div>
</div>
</div>
<div v-if="hasError">
<validation-errors v-if="errors['variationProducts.'+index]" :errors="errors">
{{ errors['variationProducts.'+index][0] }}
</validation-errors>
</div>
</div>
<div class="float-right">
<button @click.prevent="add" class="btn btn-success">Add</button>
<button @click.prevent="remove(index)" class="btn btn-danger">Remove</button>
</div>
<br>
<br>
<hr>
</div>
<input type="submit" class="btn btn-primary" value="Submit">
</form>
</template>
Here is my JS.
<script>
import ValidationErrors from './ValidationErrors.vue';
export default {
components: {
'validation-errors': ValidationErrors,
},
data () {
return {
variationProducts: [],
categories: [
{ id: 1, name: 'Technology'},
{ id: 2, name: 'Business'},
{ id: 3, name: 'Marketing'},
{ id: 4, name: 'Development'},
{ id: 5, name: 'Engineering'},
],
category: 0,
activeVariationProducts: [],
count: 1,
errors: {},
hasError: false,
}
},
methods: {
add: function() {
this.count++;
this.errors = {};
this.hasError = false;
this.variationProducts.push({ id: this.count });
},
remove: function (index) {
if ( this.variationProducts.length > 0 && index > -1) {
this.variationProducts.splice(index, 1);
} else {
alert('Must have at least one input!')
}
},
onSubmit: function() {
console.log(this.$refs.variationProducts.value);
},
generateVariationProducts: function(num) {
for(let i = 1; i <= num; i++) {
let activeVariationProduct = {
id: i,
name: 'Product '+ i,
category_id: i
};
this.activeVariationProducts.push(activeVariationProduct);
}
},
},
computed : {
filteredVariationProducts: function () {
let categoryId = parseInt(this.category);
if (categoryId !== 0) {
let filteredVariationProducts = this.activeVariationProducts.filter((variationProduct) => {
return variationProduct.category_id === categoryId;
});
return filteredVariationProducts;
} else {
let filteredVariationProducts = this.activeVariationProducts;
return filteredVariationProducts;
}
}
},
created () {
this.variationProducts.push({ id: this.count });
this.generateVariationProducts(10);
},
}
</script>
Upvotes: 3
Views: 4415
Reputation: 1311
Here is a sample code. This code Shows how you can use multiple Checkboxes that is generated dynamically and how to make them isolated -
new Vue({
el : "#app",
data : {
Items : ["One", "Two", "Three"],
newCheckbox : "",
SelectedItems : {
'One' : "",
'Two' : "",
'Three' : "",
},
},
methods:{
add:function(){
Vue.set(this.SelectedItems, this.newCheckbox, false);
this.Items.push(this.newCheckbox);
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.22/vue.min.js" type="text/javascript"></script>
<div id="app">
<div>
<label v-for="(item, index) in Items">
<input type="checkbox" v-bind:key="index" v-model="SelectedItems[item]"> {{ item }}
</label>
</div>
<div>
<input type="text" v-model="newCheckbox">
<button @click="add">Add</button>
</div>
<div>
Output : {{ SelectedItems }}
</div>
</div>
You can dynamically add new checkbox and still they are isolated
Upvotes: 5