Search code examples
javascriptractivejs

Using radio buttons with 2-way-binding and iteration in ractive.js


I wonder if it is possible to use ractive.js' 2-way-binding with a nested iteration section. What I need is to iterate over the answerOptions for each calibration. My template looks like this:

<script id="calibration-view" type="text/html">
<div id="calibrations">
    {{#each calibrations :num}}
    <div id="calibration">
        <div id="answer-options-{{num}}">
            {{#each answerOptions}}}
            <label><input type="radio" name="{{bindThisValuePerAnswerOption}}" value={{id}}>{{option}}</label>
            {{/each}}
        </div>
    </div>
    {{/each}}
    <button on-click="submit">Submit</button>
</div>

What currently happens is that all inputs will have the same binding of:

name="{{bindThisValuePerAnswerOption}}"

I've been trying to solve this for a while now and hope there is a way.

Thank you in advance!


Solution

  • The easiest way is to create a <Calibration> component, as that creates a new context for the name binding. Unfortunately there's a bug in the most recent stable version that prevents this from working – it's fixed in the edge version (which will be released as 0.8 in the near future), used below.

    Ractive.components.Calibration = Ractive.extend({
      template: `
        <div class="calibration">
          <div id="answer-options-{{num}}">
            {{#each answerOptions}}
              <label><input type="radio" name="{{selected}}" value={{id}}>{{option}}</label>
            {{/each}}
      	  </div>
        </div>
      `
    });
    
    var ractive = new Ractive({
      el: 'main',
      template: `
        <div id="calibrations">
          {{#each calibrations :num}}
        	<Calibration selected='{{selections[num]}}'/>
          {{/each}}
          <button on-click="submit">Submit</button>
    	</div>
      
        <pre>{{JSON.stringify(selections)}}</pre>
      `,
      data: {
        selections: [
          'b', 'f'
        ],
        calibrations: [
          {
            answerOptions: [
              { id: 'a', option: 'A' },
              { id: 'b', option: 'B' },
              { id: 'c', option: 'C' }
            ]
          },
          {
            answerOptions: [
              { id: 'd', option: 'D' },
              { id: 'e', option: 'E' },
              { id: 'f', option: 'F' }
            ]
          }
        ]
      }
    });
    <script src='http://cdn.ractivejs.org/edge/ractive.min.js'></script>
    <main></main>