Diskdrive
Diskdrive

Reputation: 18855

Making Meteor reactive for html elements

So I have a modal box that allows the user to edit / save some data.

I just want to add that unlike other Meteor apps, I don't want to save the data straight away - I want the user to fill in all the fields before hitting save where it will save to the database and send to server etc. This is mainly because I want the user to be able to hit the "cancel" button to revert all changes.

I have a drop down box at the start of the form where depending on the value, fields will be shown or hidden

                            <select class="form-control" id="ddlNewInputType" placeholder="Enter your input type">
                            <option value="input">Input</option>
                            <option value="formula">Formula</option>
                        </select>

And I have a handlebar around a field like this to determine whether I want to show it

                {{#if isFormula }}

                    <div class="row">
                        <input type="text"
                               id="txtNewInputFormula" placeholder="Enter formula">

                    </div>
                {{/if}}

With a helper looking like this

isFormula: ->
    $('#ddlNewInputType').val() == 'formula'

However, this doesn't work. Aside from when it first loads onto the page, it never hits isFormula, probably because Meteor doesn't consider any of the HTML elements as reactive so it never re-evaluates when the HTML element changes.

What is a suitable way to get around this? Is it possible to make something reactive explicitly in Meteor? I was also considering putting the dropdown list value into a session variable but that just seems messy because I'm going to need to manage this session variable (remember to clear it when the modal box closes etc.)

Upvotes: 2

Views: 451

Answers (1)

David Weldon
David Weldon

Reputation: 64342

Your analysis is correct - a reactive variable needs to be involved in order for your helper to reevaluate after changing the select element. The basic strategy looks like:

  1. Initialize a reactive variable when the template is created.
  2. Whenever the select changes, update the reactive variable.
  3. Read the reactive variable in your helper.

Rather than use a session variable, let's use a ReactiveVar scoped to your template. Here's an example set of modifications:

Template.myTemplate.helpers({
  isFormula: function() {
    return Template.instance().isFormula.get();
  }
});

Template.myTemplate.events({
  'change #ddlNewInputType': function (e, template) {
    var isFormula = $(e.currentTarget).val() === 'formula';
    template.isFormula.set(isFormula);
  }
});

Template.myTemplate.created = function() {
  // in your code, default this to the current value from
  // your database rather than false
  this.isFormula = new ReactiveVar(false);
};

Remember that you'll need to also do:

$ meteor add reactive-var

See my post on scoped reactivity for a full explanation of this technique.

Upvotes: 3

Related Questions