I trying to make this custom radio button component to work in vuejs. How do I make the radio button checked with a value from parent component. I know you use v-model and set it to a same value in one of the input values, but it dont seem to get it work.
component:
export default Vue.component('radioButton', {
template,
props: ['name', 'label', 'id', 'value']
})
component template:
<label class="radio" :for="id">
<input type="radio" :id="id" class="radio-button" :value="value" :name="name">
<span class="radio-circle">
</span>
<span class="radio-circle__inner">
</span>
<span class="radio-button__label">{{ label }}</span>
</label>
html:
<radio-button name="options" id="option-1" label="1" :value="selectedValue" />
<radio-button name="options" id="option-2" label="2" :value="selectedValue" />
For radio buttons, you need to pass true or false for the checked property to preset it to some state. Alternatively, your value in v-model
should be equal to value
of radio button so that it gets checked.
In the limited sample code you have posted, I believe your label is the button index like 1
, 2
, 3
and so on... And I think you want to select one of the buttons when the selectedValue
matches label
of that radio button. For example, if selectedValue is 2, then you want radio button 2 to be checked.
Assuming the above is correct, you need to make a one line change in your radio-button
component template:
<input type="radio" class="radio-button" :value="label" :name="name" v-model="value">
Note:
Your button label
is the value for radio button. This is what you would expect to set to selectedValue when you click a particular radio button.
Your value
in child component is actually selectedValue
of parent component, which indicates the radio button that is currently chosen. So this should go into v-model
So, as per the docs on Form Input Bindings, your radio button will get checked if the v-model variable is equal to the value of that radio button.
But now here is another problem: If you click on another radio button, you expect the selectedValue
in parent component to change. That is not going to happen because props
gives you one-way binding only.
To resolve this issue, you need to do a $emit from your child component (radio button) and capture it in the parent component (your form).
Here is a working jsFiddle example: https://jsfiddle.net/mani04/3uznmk72/
In this example, your form template defines radio-button components as follows:
<radio-button name="options" label="1" :value="selectedValue" @change="changeValue"/>
<radio-button name="options" label="2" :value="selectedValue" @change="changeValue"/>
Whenever the value changes inside child component, it will pass a "change" event along with the label of radio button, which gets passed to changeValue()
method of the parent form component. Once the parent component changes selectedValue
, your radio buttons update automatically.
Hope it helps!
I'd personally do it another way, to keep a v-model directive and avoid an @change event (which could be replaced by @input if any other logic has to be performed). The thing here is that I the v-model value is equal to the "value" props in the radio-button component.
props: {
value: {},
v_value: {},
....
}
So all you have to do is pass the real current value to make some checks and $emit the value on click on a label, or on change on the input if you don't have any label.
<label :for="id" @click="$emit('input', v_value)">
<input type="radio" :value="label" :name="name" :id="id" /> {{ label }}
</label>
I also added (but commented it) a version with simple html markup in case you want custom-looking radio buttons :
<div class="label" @click="$emit('input', v_value)">
<span>{{ label }}</span>
</div>
https://jsfiddle.net/Zyfraglover/ndcp8t6e/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With