Joel G Mathew
Joel G Mathew

Reputation: 8061

Read value of dynamically generated input radio using Vue

I need to use v-for to dynamically create a list, which contain input elements of type radio. I need the value in slot, to be passed to a function, when a radio button from the group is clicked. Based on this value (slot), a patient would be able to book an appointment.

I tried to use v-model to get the value of the element. But I found that I was getting a non interpolated string {{ slot }} instead of the value. Isnt it possible to interpolate variables into value attributes of input form elements?. When I tried to use just v-model without setting value, I got "on" as the value, when I tried to watch the variable used in v-model.

My problem is that I have a list of slots, each of which gets a radio button. I want to get the slot from the radio button. I tried this:

<div class="select2Buttons" id="selectRadioButtons">
    <ul v-if="activezone=='morning'" class="select-buttons">
        <li v-for="(slot, index) in morningslots" :key="index">
        <label>
            <input type="radio" name="selectedslot" value="{{ slot }}" v-model="selectedslot"/>
            <span>{{ slot }}</span>
        </label>
        </li>
    </ul>
    <ul v-else-if="activezone=='afternoon'" class="select-buttons">
        <li v-for="(slot, index) in afternoonslots" :key="index">
        <label>
            <input type="radio" name="selectedslot" v-model="selectedslot" value="{{ slot }}" />
            <span>{{ slot }}</span>
        </label>
        </li>
    </ul>
    <ul v-else-if="activezone=='evening'" class="select-buttons">
        <li href="#" v-for="(slot, index) in eveningslots" :key="index">
        <label>
            <input type="radio" name="selectedslot" v-model="selectedslot" value="{{ slot }}" />
            <span>{{ slot }}</span>
        </label>
        </li>
    </ul>
</div>

The rendered html looks like this:

<ul class="select-buttons" data-v-43dd0583="">
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" data-com.bitwarden.browser.user-edited="yes" value="{{ slot }}"><span data-v-43dd0583="">4:00 PM - 4:10 PM</span></label></li>
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" data-com.bitwarden.browser.user-edited="yes" value="{{ slot }}"><span data-v-43dd0583="">4:10 PM - 4:20 PM</span></label></li>
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" data-com.bitwarden.browser.user-edited="yes" value="{{ slot }}"><span data-v-43dd0583="">4:20 PM - 4:30 PM</span></label></li>
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" value="{{ slot }}"><span data-v-43dd0583="">4:30 PM - 4:40 PM</span></label></li>
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" value="{{ slot }}"><span data-v-43dd0583="">4:40 PM - 4:50 PM</span></label></li>
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" value="{{ slot }}"><span data-v-43dd0583="">4:50 PM - 5:00 PM</span></label></li>
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" value="{{ slot }}"><span data-v-43dd0583="">5:00 PM - 5:10 PM</span></label></li>
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" data-com.bitwarden.browser.user-edited="yes" value="{{ slot }}"><span data-v-43dd0583="">5:10 PM - 5:20 PM</span></label></li>
    <li href="#" data-v-43dd0583=""><label data-v-43dd0583=""><input type="radio" name="selectedslot" data-v-43dd0583="" data-com.bitwarden.browser.user-edited="yes" value="{{ slot }}"><span data-v-43dd0583="">5:20 PM - 5:30 PM</span></label></li>
</ul>

Part code:

watch: {
    selectedDate: {
    handler(newDate) {
        console.log(`Watcher triggered for selectedDate. New value is`);
        console.log(newDate);
        console.log(this.selectedDate);
    },
    immediate: true,
    deep: true,
    },
    selectedslot: {
    handler(newSelectedSlot) {
        console.log(`Watcher triggered for selectedslot. New value is`);
        console.log(newSelectedSlot);
        console.log(this.selectedslot);
    },
    immediate: true,
    deep: true,
    },
},

Console:
(When v-model alone used)

    Watcher triggered for selectedslot. New value is
        on
        on

When value was set to {{ slot }}:  
    Watcher triggered for selectedslot. New value is
    on
    on 

And my page looks like this: Screenshot

Edit: I was able to use @click="methodName(slot) to solve my problem, without using v-model or setting a value for the input element.

Code that works:

<input type="radio" name="selectedslot" @click="setSelectedSlot(slot)" />

And in my method:

setSelectedSlot(slot) {
  console.log(`Got value of slot as ${slot}`);
  this.selectedslot = slot

},

But I was unable to let go of my feeling that there must be something better.

Upvotes: 2

Views: 2953

Answers (1)

tony19
tony19

Reputation: 138286

You currently have value="{{ slot }}", which sets the radio button's value to be the literal string "{{ slot }}".

To bind value, use the v-bind directive (or its : shorthand):

<input type="radio" :value="slot" v-model="selectedSlot">

demo

Upvotes: 4

Related Questions