2
votes

I am struggling to understand how Meteor adds event bindings to templates.

I have a template with multiple anchors for the navigation dropdowns:

<template name="user_loggedin">
  <li  class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Select a profile..
    <b class="caret"></b></a>
    <ul class="dropdown-menu">List</ul>
  </li>

  <li  class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">
      <i class="glyphicon glyphicon-cog"></i>
      <b class="caret"></b></a>
      <ul class="dropdown-menu"> </ul>
    </li>
</template>

And I try to bind a click event to show the dropdown menus:

Template.user_loggedin.events({
  "click a.dropdown-toggle": function(e,tml) {
  $(e.target).siblings('.dropdown-menu').toggle()
  }
})

However, the event only seems to bind to the first anchor element, not all of those matching the 'a.dropdown-toggle' selector.

The same problem occurs for templates containing dynamic elements derived from collections. I'd just assumed the Meteor template events method would work in the same way as $('a.dropdown.menu').on(...

I suspect this is to do with Meteor not having rendered all the template's DOM elements before the events are bound. I've seen solutions using Meteor.template.rendered to bind events after rendering, but this seems messy considering Meteor are deprecating rendered method in the next release.

Is there another way?

1

1 Answers

0
votes

No. The event handler is specified for the template and is not "bound" to an element. So your event handler will definitely be executed if any anchor element with class dropdown-toggle is clicked.

The problem you are experiencing is probably caused by the use of e.target instead of e.currentTarget in your event handler. From the Meteor docs:

target

The element that originated the event.

currentTarget

The element currently handling the event. This is the element that matched the selector in the event map. For events that bubble, it may be target or an ancestor of target, and its value changes as the event bubbles.

In the first case both e.target and e.currentTarget are a.dropdown-toggle and everything works as expected. In the second case, however, e.target is i.glyphicon.glyphicon-cog while e.currentTarget is a.dropdown-toggle (which is what you want to have).

So please try to edit your event handler to look like this:

Template.user_loggedin.events({
  "click a.dropdown-toggle": function(e,tml) {
      $(e.currentTarget).siblings('.dropdown-menu').toggle()
  }
});

About your second problem with the dynamic elements: can you provide an example?