Vue v-model not reactive with BS4 radio button group
Asked Answered
A

2

12

I'm hoping I'm just missing something simple because I've been looking at this for too long, but I'm stumped.

I have a form with inputs bound to vuejs. I have a group of 2 radio buttons for selecting the "gender", and the binding is working perfectly. If I click on either of the radio buttons, I can see the data change in the vue component inspector.

But I'm trying to change the radio buttons to a Bootstrap 4 button group, and can't seem to get the v-model binding to work. No matter what I try, the gender_id in my vue data is not getting updated when I click either of the buttons in the button group.

The form input values are being fed in through vue component properties, but for simplicity, my data for the radio buttons/button group would look like this:

export default {
    data() {
        return {
            genders: {
                1: "Men's",
                2: "Women's"
            },
            gender_id: {
                type: Number,
                default: null
            }
        }
    }
}

Here is the code I have for the radio button version (which is working properly):

<div class="form-group">
    <label>Gender:</label>
    <div>
        <div class="form-check form-check-inline" v-for="(gender, key) in genders" :key="key">
            <input type="radio"
                class="form-check-input"
                name="gender_id"
                :id="'gender_' + key"
                :value="key"
                v-model.number="gender_id">
            <label class="form-check-label" :for="'gender_' + key">
                {{ gender }}
            </label>
        </div>
    </div>
</div>

Here is the button group version that is not properly binding to the gender_id data in vue.

<div class="form-group">
    <label>Gender:</label>
    <div>
        <div class="btn-group btn-group-toggle" data-toggle="buttons">
            <label class="btn btn-outline-secondary" v-for="(gender, key) in genders" :key="key">
                <input type="radio"
                    class="btn-group-toggle"
                    name="gender_id"
                    :id="'gender_' + key"
                    :value="key"
                    autocomplete="off"
                    v-model.number="gender_id">
                {{ gender }}
            </label>
        </div>
    </div>
</div>

I've been using the following Boostrap 4 documentation to try to get this working. https://getbootstrap.com/docs/4.0/components/buttons/#checkbox-and-radio-buttons

In the documentation for button groups they don't even include the value property of the radio inputs, whereas they do include it in the documentation for form radio buttons. https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios

Is this for simplicity or do button groups of radio buttons not even return the value of the checked button?

I see other threads stating that buttons groups are not meant to function as radio buttons, but if that's true for BS4, then why would Bootstrap have button groups with radio buttons as they do in their documentation referenced above? If you can't retrieve the checked state, then why not just use a <button> instead of <label><input type=radio></label>?

Any ideas as to what I'm doing wrong and/or not understanding correctly?

Thanks so much!

Amphichroic answered 21/3, 2018 at 18:48 Comment(0)
A
23

Thanks so much to @ebbishop for his helpful insights.

The issue was related to vue and bootstrap both trying to apply javascript to the buttons in the button group.

To get around this issue, it was as simple as removing data-toggle="buttons" from the button group. By removing the data-toggle attribute, the bootstrap js is not applied and vue can manage the button group.

Amphichroic answered 30/3, 2018 at 17:26 Comment(3)
Thanks, for the love of god I thought I will go crazy.Gotham
Thank you much. I've just started adapting vue-bootstrap for my needs (that's a head pain) but all I have to do is removing the attribute.Epileptoid
Also will need to add this to the label: v-bind:class="{ active: isActive }"Spears
S
3

Nothing is actually wrong your use of v-model here.

However: you must add the class "active" to the <label> that wraps each radio-button <input>.

See this fiddle for a working example.

Is that what you're after?

Stotts answered 21/3, 2018 at 20:45 Comment(6)
Thanks ebbishop! Your input is helpful, especially for having a button in the button group auto-selected when the form loads for an item edit. But unfortunately, adding the "active" class isn't affecting the larger issue of the vue model not binding to the radio button fields. Clicking on a button in the button group still does not update the gender_id in the data of the vue instance.Amphichroic
@CICSolutions: Take a look at the header content in the fiddle- that number that is displayed is gender_id. The gender_id is also what drives the class-binding.Stotts
Ahhh ... great fiddle, thank you. hmmm ... my code is right and matching what is in the fiddle, so the problem must be outside this code. I have a larger, more-complicated form, but it's not throwing any js errors. Strange ... my button group is getting the 'active' class on-click w/o the class binding, but if i remove the class binding in the fiddle, the buttons don't stay highlighted. I definitely appreciate your insight and help. I'll have to keep digging to find the root cause of the model variable not binding like it is in your fiddle. Thanks @ebbishop!Amphichroic
oh @ebbishop, I see you're not pulling in the bootstrap.js in your fiddle. Maybe my issue is including bootstrap.js and having conflicting functionality between bootstrap.js and vue.js? I'll give that a try :)Amphichroic
Yes, that seems to be the issue. If I pull the standard jquery, popper and bootstrap javascript libraries into your fiddle, the model binding stops working. The culprit is the jquery library. Once removed the model binding starts working again. jsfiddle.net/3e9ax7sy/19 Thank you so much @Stotts for helping me learn how to debug better!Amphichroic
@Amphichroic Glad you sorted it out! And - it's always helpful to explicitly include in the question all the libraries you are using! :)Stotts

© 2022 - 2024 — McMap. All rights reserved.