Reputation: 203
I am a beginner to Vue, and learning something by doing. I was able to make a checkbox reusable, but getting some weird result for radio buttons.
I have the data in an array format in ProgramDesign.vue
:
data() {
return {
strategies: [
"Not Important",
"Slightly Important",
"Moderately Important",
"Very Important",
"Extremely Important",
],
};
},
These are the options that get repeated on every question. I made a separate component for the radio like this:
<template>
<div>
<span v-for="strategy in groups" :key="strategy">
<input :id="strategy" class="radio-style" name="strategy" type="radio" />
<label :for="strategy" class="radio-style-3-label">{{strategy}}</label>
</span>
</div>
</template>
<script>
export default {
props: {
groups: Array,
},
};
</script>
This is how it's used in ProgramDesign.vue
:
<p>first question goes here ?</p>
<RadioButton :groups="strategies" />
<div class="line"></div>
<p>second question goes here ?</p>
<RadioButton :groups="strategies" />
I was able to get the reusable output, but when I click on the radio button for the second question, the buttons for the first question get selected. How can I fix this?
Upvotes: 3
Views: 1117
Reputation: 138696
The problem is the input
IDs and names are not unique between component instances, as can be seen in the rendering of your two RadioButton
components (simplified for brevity):
<!-- RadioButton 1 -->
<div>
<span>
<input id="Not Important" name="strategy" type="radio">
<label for="Not Important">Not Important</label>
</span>
</div>
<!-- RadioButton 2 -->
<div>
<span>
<input id="Not Important"❌ name="strategy"❌ type="radio">
<label for="Not Important">Not Important</label>
</span>
</div>
Each label
is linked to an input
by matching the for
and id
attributes, such that clicking the label
causes the linked radio input
to change values. When there are multiple input
s with the same identifier, the browser links the label
to the first matching input
, causing the behavior you observed.
The name
must also be unique between groups (RadioButton
instances), since the browser creates radio groups of input
s that have matching names.
Alternatively, a label
and input
can be linked by putting the input
inside the label
, resolving the id
/for
duplication (and improving readability):
<label>
<input name="strategy" type="radio">
Not Important
</label>
And one way to resolve the duplicate name
s is to base the name on a counter incremented per instance:
<template>
<div>
<label v-for="strategy in groups" :key="strategy">
<input :name="'strategy' + groupId" type="radio">
{{strategy}}
</label>
</div>
</template>
<script>
let groupId = 0
export default {
props: {
groups: Array
},
data() {
return {
groupId: groupId++
}
}
}
</script>
Upvotes: 5