adrianmcli
adrianmcli

Reputation: 1996

Re-applying Event Listeners in Meteor Template for Newly Created Elements

Some background: In my app, I have these input text-boxes and when you type into them, it uses the Session to hold a reactive variable so that the user can see a live preview of what they are typing.

I want to let a user click on a button to add a new input box. And whenever the user types into that new input box, it should also generate a live preview in the same way that the first one did. However, it seems that the event handler is not applied to those newly created elements. As a result, the live preview does not update until I type something into the original input box again.

Template.makeEntry.helpers({
    goals: function() {
        return Session.get('todayGoals');
    }
});

Template.makeEntry.events({
  'input .goal': function(e) {
    var tempGoals = [];
    $('.goal').each(function(i){

        tempGoals.push($(this).val());
    });
    Session.set('todayGoals',tempGoals);
  },
  'click .add-goal': function(e) {

    var lastGoal = $('.goal').last();

    $('<input class="goal" type="text" name="goal" placeholder="Type your goal here...">').insertAfter(lastGoal);
  }
});

Template.makeEntry.rendered = function(){
    Session.set('todayGoals',[]);
}

HTML:

<template name="makeEntry">
    <h1>Sunday, February 1st</h1>
    <hr>
    <input class="goal" type="text" name="goal" placeholder="Type your goal here...">
    <button class="add-goal">Add</button>
    {{#if goals}}
        <ul>
            <li>Today's Goals
                <ul>
                    {{#each goals}}
                        <li>{{{this}}}</li>
                    {{/each}}
                </ul>
            </li>
        </ul>
    {{/if}}
</template>

Upvotes: 2

Views: 376

Answers (1)

jimmiebtlr
jimmiebtlr

Reputation: 444

Try not to manipulate the DOM whenever possible outside of Blaze.

Template.makeEntry.created = function(){
  Session.set('todayGoals',[""]);
}

Template.makeEntry.events({ 
  'click .add-goal': function(){
    var goals = Session.get('todayGoals');
    goals.push("");
    Session.set('todayGoals', goals);
  }
});

Template.makeEntry.helpers({
  'goal': function(){
    return Session.get("todayGoals");
  } 
});

and in the html

<template name="makeEntry">
  ...
  {{#each goal}}
    ... do something with goal
    <input class="goal" type="text" name="goal" placeholder="Type your goal here...">
  {{/each}}
</template>

Upvotes: 3

Related Questions