[Prototype-core] Wish for Prototype 1.7 final: document.on("submit")

111 views
Skip to first unread message

Mislav Marohnić

unread,
Apr 23, 2010, 1:45:31 PM4/23/10
to Prototype.js core,
The "submit" event doesn't bubble up in Internet Explorer after it originates in a form. That makes it impossible to catch with event delegation:

document.on("submit", function(e) { ... })

Kangax wrote about a way we can detect even support without browser sniffing: http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
We have good custom events support, so we should be able to emulate submit event bubbling in IE. There are a couple of approaches:

1) Stick a real "submit" handler directly on each form and make it fire a custom "submit" event on the form's parent:

$$('form').invoke('observe', 'submit', ...)

Pros: easy.
Cons: doesn't work with dynamically created (or inserted) forms, making this solution too brittle.

2) Forms can be submitted in two ways: clicking/tapping one of the submit buttons, or pressing Enter. Both of these events bubble, so we can detect where the submit originated from and fire a custom event from there.

Pros: works with dynamically created forms.
Cons: potentially complex solution. Unnecessary observing of all clicks and keypresses on the page?

3) Observe when a form element gains focus with "focusin" event, then stick a real submit handler to it which in turn fires the custom event.

Pros: less complex than click/keypress.
Cons: not sure if it's possible to submit a form without triggering a "focusin" event first, but if it is then this solution is brittle.


I'll do more testing later. But right now, what are your opinions? Do you have any other ideas how we could hook into forms on the page and trigger custom "submit" events?

--
You received this message because you are subscribed to the Google Groups "Prototype: Core" group.
To post to this group, send email to prototy...@googlegroups.com
To unsubscribe from this group, send email to prototype-cor...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/prototype-core?hl=en

Andrew Dupont

unread,
Apr 23, 2010, 2:33:38 PM4/23/10
to prototy...@googlegroups.com
I think jQuery figured out a solution for this — care to do some research, Mislav?

Cheers,
Andrew

Mislav Marohnić

unread,
Apr 23, 2010, 3:11:23 PM4/23/10
to prototy...@googlegroups.com
On Fri, Apr 23, 2010 at 20:33, Andrew Dupont <goo...@andrewdupont.net> wrote:
I think jQuery figured out a solution for this — care to do some research, Mislav?

I remember their release notes, and I did a lot of research too. They use click+keypress.

Mislav Marohnić

unread,
Apr 28, 2010, 5:33:26 PM4/28/10
to prototy...@googlegroups.com
I've implemented "submit" and "change" events bubbling in this Prototype 1.7 plugin:

Stick it in your projects, give it a whirl! Warning: it doesn't work with the `observe` method, you have to use `on`. Example:

document.on("submit", function(e) {
  e.findElement().findFirstElement().setValue("You're a kitty!")
  e.preventDefault()
})

It uses Kangax's feature detection to see whether the events in question are supported on the "DIV" element (that is, if they bubble or not).

Then I use the "focusin" event to discover FORM, INPUT, SELECT and TEXTAREA, then I stick handlers on them to observe real events and fire the "emulated:submit" or "emulated:change" custom events which bubble.

Finally, I monkeypatch Event.Handler#initialize to magically change attempts to observe the bubbling native event to observing the emulated event.

Known bug: if the user observes the real "submit" event directly on a form element and calls `stopPropagation()` in this handler, the "emulated:submit" event will still fire and will still bubble up. This is because I don't know how to detect whether or not stopPropagation was called, and even if I could, the order in which "submit" handlers will fire at runtime is probably not guaranteed, making this problem even more complex.

Andrew Dupont

unread,
Apr 29, 2010, 11:55:58 AM4/29/10
to prototy...@googlegroups.com
On Apr 28, 2010, at 4:33 PM, Mislav Marohnić wrote:

Known bug: if the user observes the real "submit" event directly on a form element and calls `stopPropagation()` in this handler, the "emulated:submit" event will still fire and will still bubble up. This is because I don't know how to detect whether or not stopPropagation was called, and even if I could, the order in which "submit" handlers will fire at runtime is probably not guaranteed, making this problem even more complex.

There is no way to detect whether stopPropagation was called — one of the huge flaws in the DOM2 event model. When someone calls `Event#stop`, we set a `stopped` boolean on the event object; that's the best we can do.

I'll play around with this; thanks!

Cheers,
Andrew

Mislav Marohnić

unread,
Apr 29, 2010, 5:30:09 PM4/29/10
to prototy...@googlegroups.com
On Thu, Apr 29, 2010 at 17:55, Andrew Dupont <goo...@andrewdupont.net> wrote:

There is no way to detect whether stopPropagation was called — one of the huge flaws in the DOM2 event model. When someone calls `Event#stop`, we set a `stopped` boolean on the event object; that's the best we can do.

Idea how to solve: don't allow IE to observe the real "submit" event even directly on the FORM element. Instead, have it observe the custom "emulated:submit". This way we don't have real event vs. emulated event problems; we're just dealing with bubbling emulated event and when that one is stopped from propagation, we don't have edge cases.

The change simply means removing some if/else clauses from the plugin.
Reply all
Reply to author
Forward
0 new messages