Search code examples
vue.jsradio-button

Using radio buttons to set item's state with Vue.js


I currently have a table of categories that I iterate and display as a table, where every row has a group of radio buttons that can set the state of a category:

<tr v-for="cat in categoryList">
  <div class="btn-group btn-group-toggle" data-toggle="buttons">
  <label class="btn btn-secondary">
    <input type="radio" v-bind:name="'cs-' + cat.id" v-bind:id="'cs-neutral-' + cat.id" value="neutral" v-model="cat.state"> Neutral
  </label>
  <label class="btn btn-secondary">
    <input type="radio" v-bind:name="'cs-' + cat.id" v-bind:id="'cs-good-' + cat.id" value="good" v-model="cat.state"> Good
  </label>
  <label class="btn btn-secondary">
    <input type="radio" v-bind:name="'cs-' + cat.id" v-bind:id="'cs-bad-' + cat.id" value="bad" v-model="cat.state"> Bad
  </label>
  </div>
</tr>

However when displayed neither a correct radio button gets set, neither the item.state updates on change. How to fix this?


Solution

  • Make sure that you use this.$set to update array, otherwise Vue will not keep track of changes.

    Documentation

    Codepen


    HTML:

    <div id="app">
      <table>
        <tr v-for="cat in categoryList">
          <td>
            <label>
              <input type="radio" :name="'cs-' + cat.id" :id="'cs-neutral-' + cat.id" value="neutral" v-model="cat.state"> Neutral
            </label>
    
            <label>
              <input type="radio" :name="'cs-' + cat.id" :id="'cs-good-' + cat.id" value="good" v-model="cat.state"> Good
            </label>
    
            <label>
              <input type="radio" :name="'cs-' + cat.id" :id="'cs-bad-' + cat.id" value="bad" v-model="cat.state"> Bad
            </label>
          </td>
        </tr>
      </table>
     </div>
    

    Javascript:

    new Vue({
      el: "#app",
    
      data: {
        categoryList: [
          { id: 1, state: "neutral" },
          { id: 2, state: "neutral" },
          { id: 3, state: "neutral" },
          { id: 4, state: "neutral" },
        ]
      }
    })