Search code examples
vue.jsradio-button

Vue.js radio button not checked by default


I'd like to make default checked on radio buttons inside a v-for loop. Here is the code:

  <ul v-for="p in photos">
        <li>
          <div>

          <div>
            <div>
              Visibility: {{p.visible}}
            </div>                


            <strong>Visibility setting</strong><br>
            <input type="radio" v-model="p.visible" name="visibility" value="all" :checked="p.visible == 'all'"> All <br>
            <input type="radio" v-model="p.visible" name="visibility" value="fav" :checked="p.visible == 'fav'"> My favorites <br>
            <input type="radio" v-model="p.visible" name="visibility" value="none" :checked="p.visible == 'none'"> No one

          </div>
            <div><img" v-bind:src="BASE_URL +'/uploads/' + userId + '/'+ p.imgId" /> </div>
        </div>          


      </li>

      </ul>

I followed this answer.

While I can see Visibility of each item is being printed, the default radio buttons of each photo are not checked as expected.

Here is the photos array which I receive from the server when the component is created:

   [ 
        {
            "id" : "5bcebb6efeaea3147b7a22f0",
            "imgId" : "12710.png",
            "visible" : "all"
        }, 
        {
            "id" : "5bcebbf0feaea3147b7a22f1",
            "imgId" : "62818.png",
            "visible" : "fav"
        }, 
        {
            "id" : "5bcec010feaea3147b7a22f2",
            "imgId" : "36740.png",
            "visible" : "none"
        }
    ],

What is wrong here and how can I fix it?


Solution

  • Don't use :checked:

    v-model will ignore the initial value, checked or selected attributes found on any form elements. It will always treat the Vue instance data as the source of truth. You should declare the initial value on the JavaScript side, inside the data option of your component.

    If v-model is the same as value it will return true for that checkbox. Your fixed fiddle:

    new Vue({
      el: '#app',
      data: {
        photos: [{
            "id": "5bcebb6efeaea3147b7a22f0",
            "imgId": "12710.png",
            "visible": "all"
          },
          {
            "id": "5bcebbf0feaea3147b7a22f1",
            "imgId": "62818.png",
            "visible": "fav"
          },
          {
            "id": "5bcec010feaea3147b7a22f2",
            "imgId": "36740.png",
            "visible": "none"
          }
        ],
      }
    })
    <script src="https://unpkg.com/vue"></script>
    
    <div id="app">
    
      <ul v-for="(p, index) in photos">
        <li>
    
          <div>
            Visibility: {{p.visible}}
          </div>
    
          <strong>Visibility setting</strong><br>
          <input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="all"> All <br>
          <input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="fav"> My favorites <br>
          <input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="none"> No one
    
        </li>
      </ul>
    
    
    
    </div>

    Now each radio group has it's own name, with v-model targeting that group (note the index).