'Workaround for IE's Non-Bubbly Submit Events
I'm working on a large web application with a lot of AJAX whose event handling has gotten out of control. I'm trying to set up an event delegation system to manage all of it, but am wondering if there's a workaround for IE's non-bubbling form submits (there are a lot of forms that get inserted/updated via AJAX). The best thing I've come up with is executing a bit of javascript to reload submit handlers every time I get a response from an AJAX call, but this seems ugly. Any ideas?
Also, does anyone have a good reference for which events don't correctly propagate in different versions of IE? I've had trouble finding good information (though this other question has a bit).
A real example from the site: there is in-place editing of some user content. Doing event delegation, I would have the body listen for submit events and then see what element triggered the event and handle it accordingly. Since submits don't bubble in IE, this won't work. The $5 solution would be to do event delegation for all other events and handle submits using something like this in Prototype:
// call this onload:
$$('form').invoke('observe', 'submit', function(event) { /*delegate*/ });
But this won't work for forms that are created dynamically (I'd have to re-instantiate the handler every time as mentioned above), and the whole thing would just be nicer if I could "make" form submits bubble in IE and just do plain delegation everywhere (no special cases, etc).
Solution 1:[1]
Can you make the forms return false and just look for the CLICK event on the submit buttons instead of the form submit event? Then submit the forms programatically via your AJAX calls.
Solution 2:[2]
Rails 3 rails.js has solved this issue by detecting if the browser supports submit event bubbling, if not then bind the onSubmit method to the handler on the first focus event of the form. Pretty neat.
Check out
http://github.com/rails/rails/commit/f61d923d284062b4e4864d81c603157020198d06
Solution 3:[3]
One technique you can try is to have only two forms: a "working" form and a hidden "submitting" form and only have these two forms on the page.
The "working" form is what is displayed to the user - it's just a container and can contain elements from various forms. Various buttons on the form don't actually submit, but call a form handler/validation routine in JavaScript.
The handler/validation routine dynamically sets the action of the "submitting" form and adds the required elements to that form dynamically so it can be submitted.
This way you are never adding and removing from tags themselves, you're just changing the appearance and behavior of the two main ones, thus avoiding all the nasty event manipulation.
Solution 4:[4]
Matt Kantor, I strongly suggest you have a look at NWEvents. As you said it actually forces bubbling in IE and make "event delegation" available for any other event in a cross-browser way.
NWEvents source code is on GitHub.
Solution 5:[5]
Another option to consider may be reglib.
Latest trunk version has an implementation that allows delegation of submit
Solution 6:[6]
Options I've considered thus far:
- The crappy solution that I posted in the question itself.
- The Inline Cop-out - Always guaranteed to work, and has relatively low overhead, but is incredibly obtrusive. I'd have to adapt this idea to work with Prototype (which wouldn't really be hard, I'd probably just write an Event.fix(event) function that stops the event then re-fires it to propagate on its merry way).
- NWEvents - I didn't get a chance to fiddle with this too much, but supposedly this forces all events to bubble. Looking at the source, I'm not sure that this actually works for dynamically created elements. I'll have to play with it some more.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | roborourke |
| Solution 2 | Alex Le |
| Solution 3 | Diodeus - James MacFarlane |
| Solution 4 | Diego Perini |
| Solution 5 | Bill the Lizard |
| Solution 6 |
