javascriptcanjscanjs-view

comparing values from two different context using mustache and canjs


Lets say I have this mustache template below. contacts and categories are basically an array of objects:

<script type="text/mustache" id="contactsList">
  <ul class="clearfix">
    {{#contacts}}
    <li class="contact span8">
    <a href="javascript://" class="remove"><i class="icon-remove"></i></a>
    <form>
    <div class="row">
      <div class="span2">
        <img src="img/canjs.jpg" width="100" height="100">
      </div>
      <div class="span3">
        <input type="text" name="name" placeholder="Add Name" value="{{name}}">
        <select name="category">
          {{#categories}}
            <option value="{{data}}" {{sameCategory category data}}>
              {{name}}
            </option>
          {{/categories}}
        </select>
      </div>
      <div class="span3">
        <label>Address</label>
        <input type="text" name="address" value="{{address}}">
        <label>Phone</label>
        <input type="text" name="phone" value="{{phone}}">
        <label>Email</label>
        <input type="text" name="email" value="{{email}}">
      </div>
    </div>
    </form>
    </li>
    {{/contacts}}
  </ul>
</script>

What I want to do is generate "selected" within the option tag by comparing the contacts|category and categories|data.

so what I did was to implement the sameCategory like this:

can.Mustache.registerHelper('sameCategory', function(contactCategoryId, categoryId) {
console.log(contactCategoryId);
console.log(categoryId);
var result = contactCategoryId == categoryId ? "selected" : "";
console.log(result);
return result;
});

Unfortunately, im getting an object for both param instead of strings so my equality condition fails. What am I doing wrong? is there a better way to do this besides registerhelper?

supporting data:

var CONTACTS = [
  {
    id: 1,
    name: 'William',
    address: '1 CanJS Way',
    email: 'william@husker.com',
    phone: '0123456789',
    category: 'co-workers'
  },
  {
    id: 2,
    name: 'Laura',
    address: '1 CanJS Way',
    email: 'laura@starbuck.com',
    phone: '0123456789',
    category: 'friends'
  },
  {
    id: 3,
    name: 'Lee',
    address: '1 CanJS Way',
    email: 'lee@apollo.com',
    phone: '0123456789',
    category: 'family'
  }
];

var CATEGORIES = [
  {
    id: 1,
    name: 'Family',
    data: 'family'
  },
  {
    id: 2,
    name: 'Friends',
    data: 'friends'
  },
  {
    id: 3,
    name: 'Co-workers',
    data: 'co-workers'
  }
];

I took these code from the examples Diving into CanJS article.


Solution

  • I was checking out your code on a fiddle, and I couldn't replicate it, though perhaps you were getting can.computes that you would need to run as function before you got the values.

    However, that said, the helper is entirely unnecessary with the can/view/bindings plugin. Just set can-value="category" on your select and it will auto-magically select the correct option (and update the value when changed).

    Demonstrated in a fiddle: http://jsfiddle.net/air_hadoken/g725X/1/

    <select name="category" can-value="category"> {{#categories}} <option value="{{data}}" > {{name}} </option> {{/categories}} </select>