Binding a String Array to a Checkbox List

This examples shows how to bind an array of values to a list of checkboxes each representing a possible value in the array.

In this example, we are writing a simple user administration page. There are three possible roles that a user can be assigned to, and each user can be assigned to one or more of these roles.

The roles available are:

  • Admin
  • ReportViewer
  • UserManager

An individual user objects look something like this:

{ id: 1, name: 'User A', roles: ['Admin', 'ReportViewer'] },

Where the roles array represents which roles the user belongs to.

What we want to do with data binding, is display a list of checkboxes for each possible role next to each user that will display and allow the administrator to edit the roles contained in the user array.


ViewModel

This is a very simple view model that sets up an array of users, and an array of available roles.

(For a real application, you'd probably be getting the list of users from some web service, but here they are hardcoded for simplicity.)

export class TestPage {  
  constructor () {
    this.allRoles = ['Admin', 'ReportViewer', 'UserManager'];
    this.users = [];
  }

  activate () {
    this.users = [
      { id: 1, name: 'User A', roles: ['Admin'] },
      { id: 2, name: 'User B', roles: ['Admin', 'ReportViewer'] },
      { id: 3, name: 'User C', roles: [] },
    ];
  }

  logUser (user) {
    console.log(user);
  }
}

View

The view repeats a pair of editor rows for each user. The second row in this example shows how to display checkboxes by for-of-ing over the available roles, and how to bind each checkbox to an available role and bind its checked state to the individual user's roles array based on whether or not the item is present.

<template>  
  <div repeat.for="user of users">

    <div class="row">
      <span class="col-sm-3">Name</span>
      <span class="col-sm-9">
        <input type="text" class="form-control" value.bind="user.name">
      </span>
    </div>

    <div class="row">
      <span class="col-sm-3">Roles</span>
      <span class="col-sm-9">
        <label class="checkbox" repeat.for="role of $parent.allRoles">
          <input type="checkbox" value.bind="role" 
            checked.bind="$parent.user.roles">${role}
        </label>
      </span>
    </div>

    <div>
      <button click.trigger="$parent.logUser(user)">
        Show User In Console
      </button>
    </div>

    <hr />
  </div>
</template>  

The critical piece is here:

<div repeat.for="user of users">  
  ...
  <label class="checkbox" repeat.for="role of $parent.allRoles">
    <input type="checkbox" value.bind="role" 
      checked.bind="$parent.user.roles">${role}
  </label>
  ...
</div>