views:

417

answers:

1

Would really appreciate if anyone can help me figure out why I am unable to fire events programmatically when using event delegation in MooTools (from the Element.Delegation class).

There is a parent <div> that has a change listener on some child <input> elements. When the change event is triggered by user actions, the handler on the parent div gets triggered, but when I fire it programmatically with fireEvent on any child input, nothing happens. The basic setup is:

html

<div id="listener">
    <input type="text" id="color" class="color" />
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​</div>​​​​​​​​​​​

js

$("listener").addEvent("change:relay(.color)", function() {
    alert("changed!!");
});

$("color").fireEvent("change"); // nothing happens

The event handler on the parent div does not get called. Any help is appreciated. Cheers!


Related question: Do events triggered with fireEvent bubble at all in the DOM tree? My current hack is to dispatch the event natively which is working (but a hack nonetheless) - http://jsfiddle.net/SZZ3Z/1/

var event = document.createEvent("HTMLEvents")
event.initEvent("change", true);
document.getElementById("color").dispatchEvent(event); // instead of fireEvent
+3  A: 

this won't work too well 'as is'. the problem with event bubbling (and with programmatic firing of events) is that it may need the event object to be 'real' in order for it to contain event.target that is being matched against the relay string. also, $("color").fireEvent() won't work as color itself has no event attached to it.

to get around this, you fake the event on the parent listener by passing an event object that contains the target element like so:

$("listener").fireEvent("change", {target: $("color")});

view in action: http://www.jsfiddle.net/xZFqp/1/

if you do things like event.stop in your callback function then you need to pass on {target: $("color"), stop: $empty} and so forth for any event methods you may be referencing but the event delegation code is only interested in target for now.

Dimitar Christoff
Thanks for this approach Dimitar. However, I don't feel very comfortable firing the event on the parent directly cause that's getting too friendly with the internal workings. Also, would I be wrong to say MooTools doesn't use the DOM event dispatching mechanism, and stores event handlers for each element in the element store?
Anurag
I don't see a problem with firing the event through the parent listener. To be honest, the mootools core team are the first to admit that the current implementation of event delegation leaves things short of brilliant. I cannot comment on what is forthcoming in the near-ready 1.3 or almost-near-ready mootools 2.0 but you are correct in that events are basically in element storage under events (so you can do `var myEvents = this.retrieve("events");` and get an object with the event name as key, like `myEvents.click` and can explore it further under click.keys to find the stored functions.
Dimitar Christoff
I would also say that the native method you have used for dispatching the event is is not cross-browser compliant (fails FF) and this kind thing defeats the purpose of using a framework when you need to cater for every possible way of achieving this for all browser engines... Having said that, if you get anywhere with this, may be worth submitting it on github as a new method of the Event class, like `fireNativeEvent: function(eventType)`. Good luck
Dimitar Christoff
Thanks for the great response. I'm really looking forward to using 1.3 on my site as soon as I could. Calling the parent doesn't seem to be that big of a problem, and it's a good idea to document this or put it in our functional tests for when a MooTools version upgrade does happen, we are careful about testing these changes. That said, I was thinking of implementing a method on `Element.Event` with the exact same name `fireNativeEvent` :), to isolate changes to a single function. Right now it's not cross-browser, and won't work on IE/FF. But I will share it on github if I do write this.
Anurag