0

The scenario

Since I have a more complex checkbox I encapsulated it inside a separate component. Inside the template of the parent component I prefer using v-model to bind the value to a variable.

My approach is based on this description (https://v2.vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model) taken from the official documentation.

The problem

When I have two custom-checkbox-elements and I select the last one, the first one inside the DOM will be selected. So it seems, that the first one is consuming the event.

The code

The following snippet illustrates the checkbox component.

<template>
  <div class="checkbox-part">
    <input class="checkbox-part-input" type="checkbox" name="cb" id="cb"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
    <label class="checkbox-part-label" for="cb"
      :class="{ 'checkbox-part-label--checked': checked }"
    >
    <slot name="label"></slot>
    </label>
    <!-- removed for brevetiy -->
  </div>
</template>

<script>
export default {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: {
      type: Boolean,
    }
  }
}
</script>

How can I achieve, that the selected checkbox is updated?

6
  • 1
    This typically happens when they have the same name and v-model attribute. Did you make those unique? Commented Oct 16, 2018 at 13:14
  • The component itself is called CheckboxPart. The variable bound to v-model is called different in both parent components. Does this answer your question? Commented Oct 16, 2018 at 13:16
  • Can we see the code for that custom component? Commented Oct 16, 2018 at 13:17
  • Of course. I've just updated my post and included a snippet. Commented Oct 16, 2018 at 13:23
  • 1
    The name will always be the same. Can we see how you're passing checked in to the checkbox? Commented Oct 16, 2018 at 13:31

2 Answers 2

1

You have name of input hardcoded in component. So you probably render two input with same name ("cb" in this case) I think that you can pass input name and id as props.

This should solve your problem.

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

1 Comment

Thanks! After checking my implementation and the hint of @Ohgodwhy I've set id and name as well as the value for the labels for attribute dynamically. So it will be passed in the template of the parent components.
0

As already mentioned in the comments the problem was caused by hard-coded values for id and name inside the CheckboxPart component.

I've added two properties for name and value and inject them into the component as well.

The snippet

<!-- checkbox -->

<template>
  <div class="checkbox-part">
    <input class="checkbox-part-input" type="checkbox" 
      :name="name"
      :id="id"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
    <label class="checkbox-part-label" 
      :for="name"
      :class="{ 'checkbox-part-label--checked': checked }"
    >
      <slot name="label"></slot>
    </label>
 
    <!-- removed for brevity -->
 
  </div>
</template>

<script>
  export default {
    model: {
      prop: 'checked',
      event: 'change'
    },
    props: {
      checked: {
        type: Boolean,
      },
      name: {
        type: String,
        required: true
      },
      id: {
        type: String,
        required: true
      }
    }
  }
</script>

<!--- parent component using the one -->

<template>
  <!-- removed for brevity -->
  <!-- ... -->
 <div class="expandable-category-part-social-section">
        <checkbox-part
          v-model="isSocialIntegrationEnabled"
          :id="title + 'social-media'"
          :name="title + 'social-media'"
        >
          <template slot="label">
            <div class="checkbox-part-label-text">Final text comes here...</div>
          </template>
</checkbox-part>
</div>

<!-- ... -->

</template>

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.