Tarlen
Tarlen

Reputation: 3797

How to make template helper reactive?

I am using a JQueryUI slider in one of my forms to select a value within a range. I want to display this value next to the slider, which means I need to make the getter method for the slider method reactive

Template.payments.rendered = function () {
  $( "#requestAmount" ).slider({
     min: 10,
     max: 50,
     step: 1,
   });
};


Template.payments.helpers({

  requestAmount: function() {
    var value = $( "#requestAmount" ).slider( "option", "value" );
    return value;
  },
  ....

HTML

 <form class="navbar-form navbar-left">

 <div id="requestAmount"></div>
    <div class="requestAmount">
      {{requestAmount}}
    </div>
 ...

One is the correct way to accomplish this?

Upvotes: 0

Views: 451

Answers (1)

saimeunt
saimeunt

Reputation: 22696

If you want your helper to be reactive, it has to return a reactive data source such as a ReactiveVar for example (you need to meteor add reactive-var first).

We need to assign a reactive var to the slider template like this :

Template.payments.created=function(){
  this.sliderValue=new ReactiveVar(0);
};

Then we can return the value of this reactive data source in our helper

Template.payments.helpers({
  sliderValue:function(){
    Template.instance().sliderValue.get();
  }
});

Finally we have to set the reactive var value whenever our slider is changed.

Template.payments.events({
  "slidechange #requestAmount":function(event,template){
    var sliderValue=template.$("#requestAmount").slider("option","value");
    template.sliderValue.set(sliderValue);
  }
});

You may want to wrap all this in a reusable Meteor package and even publish it as a package.

HTML

<template name="UISlider">
  <div id="{{id}}" class="ui-slider">
    <div class="ui-slider-widget"></div>
    <div class="ui-slider-value">{{value}}</div>
  </div>
</template>

JS

Template.UISlider.created=function(){
  this.value=new ReactiveVar(0);
};

Template.UISlider.helpers({
  value:function(){
    return Template.instance().value.get();
  }
});

Template.UISlider.events({
  "slidechange":function(event,template){
    var value=template.$(".ui-slider-widget").slider("option","value");
    template.value.set(value);
  }
});

This reusable Meteor component could be used like this :

HTML

<template name="payments">
  {{> UISlider id="requestAmount"}}
  <p>{{sliderValue}}</p>
</template>

JS

Template.payments.helpers({
  sliderValue:function(){
    var $slider=Template.instance().$("#requestAmount");
    var sliderInstance=Blaze.getView($slider.get(0));
    return sliderInstance.value.get();
  }
});

Upvotes: 1

Related Questions