I'm working on a product configurator. I use Ractivejs.
I have two problems.

  1. if you check option1 in step1, in step2 option1 is also checked (why?)
  2. i need a way to hide color blue, if you choose Product 2 in the first step

template:

{{#steps[currentStep].options:i}}
    <div class='radio'>
      <label>
        <input type='radio' name='group{{currentStep}}' id='radio{{currentStep}}{{i}}' value='option{{currentStep}}{{i}}'>
        {{name}}
      </label>
    </div>
{{/steps[currentStep].options}}
<button on-click='gotoStep: {{currentStep + 1}}'>next</button>

Javascript:

var ractive, stepsData;

stepsData = [
    { name: 'Products', options: [
        { name: 'Product 1', price: 100 },
        { name: 'Product 2', price: 120 }
    ]},
    { name: 'Color', options: [
        { name: 'Black', price: 0},
        { name: 'White', price: 5 },
        { name: 'Blue', price: 20 }
    ]}
];

ractive = new Ractive({
    el: '#template',
    template: '#tempMain',
    data: {
        steps: stepsData,
        currentStep: 0
    }
});

ractive.on( 'gotoStep', function ( event, step ) {
  this.set( 'currentStep', step );
});
有帮助吗?

解决方案

You've got to get the radio group value to append to the right object. For this particular example, that would might mean putting it onto the options object:

{{#steps[currentStep].options:i}}
    <div class='radio'>
      <label>
          <input type='radio' name='{{../value}}' value='{{i}}'/>
        {{name}}
      </label>
    </div>
{{/}}

See http://jsfiddle.net/x63VW/1/

UPDATE: Really you should consider moving your answers to a separate object. (There's a bug in ractive that makes this template a bit longer than it needs to be, I'll walk through that next). Full example is here: http://jsfiddle.net/x63VW/3/.

{{# steps[currentStep] }}
    {{# { stepName: .name, options: options } }}
    {{#options:i}}
        {{# !exclude(stepName, name) }}
        <div class='radio'>
          <label>
              <input type='radio' name='{{responses[stepName]}}' value='{{name}}'/>
              {{name}}
          </label>
        </div>
        {{/}}
    {{/}}
    {{/}}
{{/}}

<button on-click='gotoStep: {{currentStep + -1}}'>prev</button>
<button on-click='gotoStep: {{currentStep + 1}}'>next</button>
<br>
responses:
{{#responses:r}}
    <li>{{r}}: {{.}}</li>
{{/}}

The key here is creating a responses object with a property for every step: responses[stepName]. This also enables you to provide existing responses.

In order to get the radio inputs to update, I'm causing the section to go falsey before updating:

ractive.on( 'gotoStep', function ( event, step ) {
  this.set( 'currentStep', null ); //workaround for bug
  this.set( 'currentStep', step );
});

Which means the initial section has to be capable of returning a falsey value:

{{# steps[currentStep] }}
//this would throw:
{{# steps[currentStep].options }}

The aliasing is a nicety to avoid ../../name and referencing steps[currentStep] multiple times:

{{# { stepName: .name, options: options } }}

The exclusion is managed via a filter function. Which is likely unless your logic is very simplistic.

ractive = new Ractive({
    el: '#template',
    template: '#tempMain',
    data: {
        steps: stepsData,
        currentStep: 0,
        exclude: function(stepName, optName){
            if(stepName==='Color' && optName=='Blue'){
                return this.get('responses.Products')==='Product 2'
            }
        }
    }
});

You probably would create some type of map for steps and answers and what to exclude. But this should give you an approach.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top