1

I have a checkbox component in Vue:

<template>
    <div class="checkbox">
        <input class="checkbox-input" name="input" type="checkbox" v-model="checkbox">
    </div>
</template>
  
<script>
export default {
    data(){
        return {
            checkbox: false
        };
    },
};
</script>

So in the parent component I want to control these checkbox. So here is my parent component:

<div class="card">
    <div class="card-header">
        <CheckBox />
    </div>
<div class="card-body" v-for="item in cart" :key="item.product.id">
    <div class="checkbox-area">
        <CheckBox />
    </div>
</div>

So checkbox in card-body can be added when user clicks to add. So if a user clicks 3 times, 3 checkbox are being added inside of card-body. What I am trying to achieve is, as you see in card-header there is another checkbox, and when this checkbox is clicked, I want to check all the checkboxes inside card-body, and when it is unchecked in card-header, I want to unchcecked everything inside card-body.

So do you have any idea how to achieve this?

Thanks...

3 Answers 3

1

You can try like this :

Vue.component('checkbox', {
  template: `
    <div class="checkbox">
        <input class="checkbox-input" name="input" type="checkbox" @change="getCheck" v-model="value">
    </div>
  `,
  props: {
    checked: {
      type: Boolean,
      default: false
    }
  },
  data(){
    return {
      value: this.checked
    };
  },
  methods: {
    getCheck() {
      this.$emit("set-checked", this.value)
    }
  },
  watch: {
    checked(){
      this.value = this.checked
    }
  }
})

new Vue({
  el: '#demo',
  data(){
    return {
      all: false,
      cart: [
        {id: 1, check: false},
        {id: 2, check: false},
        {id: 3, check: true},
        {id: 4, check: false}
      ]
    };
  },
  watch: {
    cart() {
      this.cart.find(c => c.check === false) ? this.all = false : this.all = true
    }
  },
  methods: {
    checkAll(val) {
      this.all = val
      this.cart = this.cart.map(c => {
        c.check = val 
        return c
      })
    },
    checkItem(id) {
      this.cart = this.cart.map(c => {
        if(c.id === id) {
          c.check = !c.check 
        }
        return c
      })
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div class="card">
    <div class="card-header">
    <p>All</p>
      <checkbox :checked="all" @set-checked="checkAll" />
    </div>
    <br/>
    <div class="card-body" v-for="item in cart" :key="item.id">
      <div class="checkbox-area">
        <checkbox :checked="item.check" @set-checked="checkItem(item.id)" />
      </div>
    </div>
  </div>
</div>

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

Comments

0

First of all you need to add some props to your Component. than a wachter to emit a sync when the Value of the checkbox changes.

<template>
    <div class="checkbox">
        <input class="checkbox-input" name="input" type="checkbox" v-model="value">
    </div>
</template>

<script>
export default {
    props: {
        checked: {
            type: Boolean,
            default: false
        }
    }
    data(){
        return {
            value: this.checked
        };
    },
    watch: {
        value(){
            this.$emit("update:checked", this.value)
        }
    }
};
</script>

on the cart you need to watch for theses changes an than you can check/uncheck all the items.

<template>
    <div class="card">
        <div class="card-header">
            <CheckBox :checked.sync="global"/>
        </div>
        <div class="card-body" v-for="item in cart" :key="item.product.id">
            <div class="checkbox-area">
                <CheckBox :checked.sync="item"/>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data(){
        return {
            global: false,
            cart: [
                false,
                false,
                false
            ]
        };
    },
    watch: {
        global(){
            for (let i = 0; i < this.cart.length; i++) {
                this.chart[i] = this.global
            }
        }
    }
};
</script>

I have not tested this code, but this should work...

9 Comments

I dont think your answers is correct, I tried it but it is not working
have you imported the checkbox component?
Yes I did same as you did, and it was already imported
can you check in the developer-tool if the value is emited when you check/uncheck a checkox?
I specified the prop to be a Boolean, you are passing an object. my guess is that you modified the varible chart? if yes you need to edit: :checked.sync="item" to something like this: :checked.sync="item.checked"
|
0

Using checkbox input as custom components can be a little tricky see if this code can help you:

code sandbox

  Vue.component('checkbox', {
    template: `
    <label>
        <input type="checkbox" :value="value" v-model="deltaValue" />
        {{ label }}
    </label>
    `,
    name: "checkbox",
    model: {
       prop: 'modelValue',
       event: 'update:modelValue'
    },
    props: {
      label: String,
      value: [Object, Boolean, Array],
      modelValue: {
        type: [Array, Boolean],
        default: () => [],
      },
    },
    computed: {
      deltaValue: {
        get() {
          return this.modelValue;
        },
        set(value) {
          this.$emit("update:modelValue", value);
        },
      },
    },
  });
  
  new Vue({
    el: '#app',
    data() {
        return {
          areAllSelected: false,
          checkedItems: [],
          cart: [
            { id: 1, name: "tablet"},
            { id: 2, name: "phone"},
            { id: 3, name: "PC" },
          ],
        };
      },
      watch: {
        areAllSelected(areAllSelected) {
          if (areAllSelected) {
            this.checkedItems = [...this.cart];
            return;
          }
          this.checkedItems = [];
        },
        checkedItems(items){
          if (items.length === this.cart.length) {
            this.areAllSelected = true;
            return;
          }
    
          if (items.length === 0) {
            this.areAllSelected = false;
          }
        }
      },
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="card">
    {{ checkedItems }}
    <div class="card-header">
      <checkbox label="check all" v-model="areAllSelected" />
    </div>
    <hr />
    <div class="card-body" v-for="product in cart" :key="product.id">
      <checkbox
        :label="product.name"
        :value="product"
        v-model="checkedItems"
      />
    </div>
  </div>
</div>

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.