Meteor multiple event handlers attached when showing and hiding templates - events

I'm having an issue with nested templates in Meteor.
If I have a template like this, with a child template inside it:
In parentTemplate.js
{{#if showParentTemplate}}
{{> parentTemplate}}
{{/if}}
<template name="parentTemplate">
{{> childTemplate}}
</template>
In childTemplate.js:
<template name="childTemplate">
<a class="someItem" href="#"></a>
</template>
When I register a click event on the element(anchor in this example), then show/hide the parent template on the DOM, I end up with an extra event listener on the anchor for each time I show the parent back on the DOM. I checked the Template.parentTemplate.onDestroy() and it is firing. That should mean the template and its events are being destroyed. I would imaging that includes destroying the child template and its events as well.
Here is a simple handler for the click event
Template.childTemplate.events({
'click .someItem' :(e,template)=>{
console.log('got it');
}
})
And to clarify, I am attaching the event listeners in the onCreated method, not the onRendered method.
I'm seeing that each time the parentTemplate is shown, the childTemplate fires the onCreated event, then multiple onRendered events. A new onRendered is added with each hide/show of the parentTemplate.
Is there something basic I'm missing here. It seems almost like there are multiple instances of the template on the DOM or the events are never destroyed. is there a correct way to destroy a Meteor template when it is hidden or removed form the DOM?

Related

"removed" event in Meteor

I want to trigger an event when an element is removed from the DOM.
In one of my templates I show a checkbox only when a condition is met:
{{#if some.thing}}
<input type="checkbox" class="checkbox">
{{/if}}
This checkbox later then is converted to a Bootstrap Toggle component.
What it does is, it hides the original checkbox and adds some markup to the document. All OK with that.
Now, if my collection changes and the condition, which previously was met, now evaluates to false, the checkbox is removed from the DOM. The node created from Bootstrap Toggle though stays present. So I want to remove the nde when the checkbox is removed.
I thought I could to this with the DOMNodeRemoved event but have some issues there:
Template.myTemplate.events({
"DOMNodeRemoved input.checkbox": function(el) {
$(el.currentTarget).bootstrapToggle('destroy');
}
});
The event fires, but somehow it ends in a cascade when I call bootstrapToggle('destroy') and the browser freezes. Also the event fires multiple times before and it makes me think this is not the correct way to watch for removed nodes in the first place.
Is there any better way to watch for removed elements and fire an event before they are deleted?
I know I could simply call a helper from my template, manually check if the node exists and delete the node with jQuery. But I'd like to see if this is possible with Meteor.events instead.
If you place the input (and the new bootstrap node/s) inside a child template, this should "just work" out of the box.
<template name="parent">
{{#if some.thing}}
{{> child}}
{{/if}}
</template>
<template name="child">
<input type="checkbox">
<!-- additional bootstrap nodes get instantiated in child -->
</template>
In the above, if some.thing === false the input and the new node/s will be removed from the DOM by Meteor automatically.

jQuery Mobile 1.4.2 Click Event Not Firing After DOM Manipulation & Page Refresh

I am trying to use single page mobile site. Basically I have a listview inside container and click event for list class.
<div role="main" class="ui-content">
<ul data-role="listview" data-inset="true">
<li class="listbtn">
</li>
</ul><!-- /listview -->
</div><!-- /content -->
I have a script for firing "listbtn" click event
$(".listbrn").click(function(){
});
this is working fine when page loads for first time
On another event, I am pulling data and replacing the whole "listview" with new items.
After DOM manipulation is successful, I have used
$('.ui-page-active .ui-listview').listview('refresh');
$.mobile.activePage.trigger('create');
as suggested on other threads.
Up to this point everything is smooth, page refreshes with new items and CSS applied nicely as expected.
Only problem is "listbtn" click event is not firing after that.
While looking for answers, I found this thread and tried to use live as suggested but after changing to live page won't load at all. Loading gif images spins forever.
Any suggestion or ideas?
jQuery 2.0
jQM 1.4.2
Thanks
You need to delegate event to dynamically added elements.
Another note, you don't need $.mobile.activePage.trigger('create');, .listview("refresh") is enough to re-enhance list-view. Not to mention that both $.mobile.activePage as well as .trigger('create') are deprecated and will be removed on jQM 1.5.
$(document).on("click", ".listbtn", function () {
/* code */
});
Demo

How do I bind events directly to existing HTML, without using any kind of views, in Ember.js?

Ember.js has a great mechanism of binding data to views, of setting triggered event handling in the view, or using a Router. But what I would need is to be able to handle events triggered in already created HTML code (by PHP, server-side).
Let me show you a simple example. I have this code:
<a id="login" href="#">Login</a>
I need to be able to route/handle the click on this link so that it gets into my Ember application.
I have been looking for ways to do this, but I can't find any.
How can I do this?
If this link is inside a DOM element which is a child of the Ember managed element, then you can use the action helper:
<a id="login" href="#" {{action doSomeStuff}}>Login</a>
This doSomeStuff event will be sent to your Ember.Router, which has to implement the handler in the appropriated route:
...: Ember.Route.extend({
doSomeStuff: function (router) {
//...
}
}),
If the link is outside your app's scope, you can register handlers on the app-related elements using JQuery:
$('a#login').click(function () {
App.router.transitionTo('the.route.path');
});
The App.router being injected at Ember app's initialization, you can access it from anywhere.
But let me say that it is not a best practice to transition from outside the router.
Last but not least, you can also pass a context to the transitionTo call.

How to pass event and other arguments in grid's context menu item handler?

I'm using Dojo 1.5, and I'm trying to create a context menu that can invocate a function myFunction passing the event and other arguments. So far I've the following code:
<div dojoType="dijit.Menu" id="bankerMenu" style="display: none;">
<div dojoType="dijit.MenuItem" onclick="copyDocuments('bankerFolder');" iconClass="dijitEditorIcon dijitEditorIconCopy">Copy to Client</div>
<div dojoType="dijit.PopupMenuItem" onclick="doNothing()" iconClass="dijitEditorIcon dijitEditorIconCopy">
<span><s:text name="CopyTo.label"/></span>
<div dojoType="dijit.Menu" id="bigsubmenu">
var="distributionList">
<div dojoType="dijit.MenuItem" onclick="myFunction(event,'bankerFolder',1)"><s:property value='distributionListName'/></div>
</div>
</div>
</div>
But it is not recognizing the 'event' that I want to pass to the function. I know I can susbtitute the call using this:
<div dojoType="dijit.MenuItem" label="Some menu item 2">
<script type="dojo/method" event="onClick" args="evt">
myFunction(evt,'bankerFolder',1);
</script>
</div>
but I would like to simplify it and used the first syntax. How can I do that?
Passing event literally would likely end up leaving you at the mercy of cross-browser inconsistencies. However, since events connected through Dojo worry about this for you, and since onClick is a widget event that already receives the event object as an argument, you should be able to get away with the following:
<div dojoType="dijit.MenuItem" onClick="myFunction(arguments[0],'bankerFolder',1)"><s:property value='distributionListName'/></div>
Also note the capital C in onClick - widget events always use camel case; they are not actual DOM events, though they are often mapped to analogous DOM events. I get the impression you were testing with capital C though, based on the problem you described encountering.
Here's a simplified example of the idea working (initially provided/suggested by Dustin Machi in the Dojo IRC channel): http://jsfiddle.net/xwFC5/5/
Following from Ken's comment to the answer above, I managed to figure this out as outlined here: http://blue-networks.net/wp/?p=37 It connects to onCellContextMenu and pulls the relevant information out of the event, saving it into the grid object.

jQuery's delegate conflict with another delegate in IE

It seems that in IE, some delegates may somehow cause another delegate to fail to work.
This is one possible case:
<html>
<head>
<script src='jquery-1.4.2.min.js'></script>
<script>
$(function() {
$('#main')
.delegate('div', 'click', function() {
alert('on div!');
})
.delegate('[name=first]', 'change', function() {
alert('first!');
})
.delegate('[name=second]', 'change', function() {
alert('second!');
})
;
});
</script>
</head>
<body>
<div id="main">
<input name="first" />
<input name="second" type="checkbox" />
<div>Test</div>
</div>
</body>
</html>
In this particular case, the handler for the checkbox won't fire.
As usual, the problem doesn't show up in other browsers.
Changing the call orders may solve an issue , but at the risk of causing another. Note that the delegate works on mutually exclusive elements so the order should be irrelevant.
What causes this?
I cannot offer an explanation; but I have encountered similar behavior in IE8. Oddly, in my case everything worked well if I rearranged bindings so that the delegate binding on one of my checkboxes came before delegate bindings on other form elements. A delegated click handler on a link before the checkbox handler did not seem to cause problems.
In my case I had one click handler on a checkbox, two change handlers on select boxes, two click handlers on radio buttons, another click handler on another class of checkboxes, and several click handlers on links.
There are a lot of variables to account for and it is difficult to account for all of them here. For example, the delegated selector for the checkbox that caused a problem for me was an id selector while the selector for the innocuous checkboxes was a class.
It seems that the problem has been resolved in the latest version of jQuery or Internet-Explorer (as of this writing, 1.5 and 9, respectively).
I ran into this as well. For some reason, reversing the order of registering the events fixed it for me. I'd love an explanation though.

Resources