Daniel Fowler
Daniel Fowler

Reputation: 395

Vue JS for updating checkboxes based on radio selection

I basically have the same question as this guy, but using Vue JS instead of jQuery.

I have a list of N groups bound to my array ensemble_groups and represented by radio buttons. Selected value is mapped to selected_group.

I have a list of actors bound to my array cast with the variables actor_id, actor_name and groups. Each actor is pre-assigned to any number of groups. They're represented by checkboxes and mapped to an array visible_actors (when checked).

Here's my Vue JS powering the above data (I imagine the method is all jacked up, and I probably need a computed property of some sort):

new Vue({
    el: '#schedule-builder',

    data: {
      selected_group: 'Entire Cast',
      visible_actors: [],

      ensemble_groups: [
        "Entire Cast",
        "Leads",
        "Dancers",
        "Children",
        "Deselect All",
      ],

      cast: [
        {
          actor_id: "123",
          actor_name: "Carl",
          groups: ["Entire Cast","Leads",],
        },
        {
          actor_id: "234",
          actor_name: "Max",
          groups: ["Entire Cast","Leads","Children",],
        },
        {
          actor_id: "345",
          actor_name: "Sheryl",
          groups: ["Entire Cast","Dancers",],
        },
        {
          actor_id: "456",
          actor_name: "Chip",
          groups: ["Entire Cast","Children",],
        },
      ],
    },
    methods: {
      selectGroup: function() {
        // uncheck all
        visible_actors=[];
        // add people in this group to visible_actors
        for person in cast {
          if (person.groups.indexOf(selected_group) > -1) {
            visible_actors.push(person.actor_id);
          }
        }
    }
})

When a user clicks on a radio button for a group, I want to select only the actors' checkboxes who are in that group. So if the user selects "Children", only the actors in the "Children" group should be checked (Max and Chip, per my example).

And, obviously, checking an actor (rather than a group) shouldn't affect the rest of the selections. I mention this because I got it partially working at one point, where selecting a group also selected the correct people, but when I clicked on a person suddenly everyone else was deselected. User can click either a group OR a person, and the expected behavior is that

Here's my HTML template:

<div id="schedule-builder">
  <div class="select-groups">
    <h3>Ensemble Groups</h3>
    <template v-for="group in ensemble_groups">
      <input name="select_group[]" id="group_@{{ $index }}"
             v-model="selected_group"
             :value="group"
             @click="selectGroup"
             type="radio">
      <label for="group_@{{ $index }}">@{{ group }}</label>
    </template>
  </div>

  <div class="select-individuals">
    <h3>Cast Members</h3>
    <template v-for="person in cast">
      <input name="actors[]" id="actor-@{{ $index }}"
             v-model="visible_actors"
             :value="person.actor_id"
             :checked="visible_actors.indexOf(person.actor_id) > -1"
             type="checkbox">
      <label for="actor-@{{ $index }}">
        @{{ person.actor_name }}
      </label>
    </template>
  </div>
</div>

Any help is appreciated... I've been banging my head on it for a couple days already.

Upvotes: 1

Views: 3340

Answers (1)

Bill Criswell
Bill Criswell

Reputation: 32921

This is a tough question to answer well but I'll try.

I would not rely on a computed property for the checked state. Let v-model handle that for you. You can do

<input 
  type="checkbox" 
  name="actors[]" 
  v-model="selected_actors" 
  :value="actor">

and that will manage the array of selected_actors for you as their values change.

I'm at work and plan on elaborating on this answer a little later but here's a fiddle of how I'd approach the situation: https://jsfiddle.net/crswll/806shzzg/7/

Upvotes: 2

Related Questions