Using arrow keys, Firefox fires dropdown onchange event after element loses focus, others don't
Reported by Scott Hyndman | April 13th, 2008 @ 10:10 PM | in Inline documentation
Problem encountered on Mac Firefox and Mac Safari
The 'change' event does not fire on combobox selects when changing selection with the keyboard. Events fire properly with select-one lists and select-multiple lists.
I have attached an example which runs without modification.
Fix (Updated with Safari fix described below)
This is a new registerCallback method for Abstract.EventObserver. It seems to be working alright for me.
registerCallback: function(element) {
if (element.type) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
// XXX: [scott] this case is added to fix select-one combos
case 'select-one':
var sz = element.readAttribute('size');
if(!sz || parseInt(sz) <= 1) { // will match null, 0 or 1
// do not use onElementEvent as the event callback directly. some browsers dispatch keypress
// before changing the value on the select, so we need to defer the call until after the change
Event.observe(element, 'keypress', (function() {
// bind() is necessary, otherwise onElementEvent is called in window scope
this.onElementEvent.bind(this).defer();
}).bind(this));
}
// fall through
default:
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}
}
Comments and changes to this ticket
-

Scott Hyndman April 13th, 2008 @ 10:12 PM
Oh, and if this system doesn't email me when you take a look, would you mind emailing me at scotty.hyndman@gmail.com?
ALSO,
If you guys were looking for developers, I'd keen. I know the framework, live and breath JavaScript, and have successfully contributed to OSS in the past.
Let me know.
Scott
-

Scott Hyndman April 13th, 2008 @ 10:20 PM
Sorry. Fix doesn't seem to cover all cases. I'm working on it.
-

Scott Hyndman April 13th, 2008 @ 10:50 PM
Safari dispatches the 'keypress' before changing the value on the select. The below script fixes that, but there is still a problem with Firefox Mac.
registerCallback: function(element) { if (element.type) { switch (element.type.toLowerCase()) { case 'checkbox': case 'radio': Event.observe(element, 'click', this.onElementEvent.bind(this)); break; // XXX: [scott] this case is added to fix select-one combos case 'select-one': var sz = element.readAttribute('size'); if(!sz || parseInt(sz) <= 1) { // will match null, 0 or 1 Event.observe(element, 'keypress', (function() { // bind() is necessary, otherwise onElementEvent is called in window scope this.onElementEvent.bind(this).defer(); }).bind(this)); } // fall through default: Event.observe(element, 'change', this.onElementEvent.bind(this)); break; } } }Alright, here are steps to reproduce. It's a little strange, but I couldn't get anything better that was reproducible.
With my fix in place, perform the following actions (Mac Firefox):
1. Drop down the combobox
2. Type (do not use mouse) 'g'. (selection should change to 'ghi')
3. Wait for a second, then type 'd'. (selection should change to 'def')
4. Wait for a second, then type 'g'. (selection should change to 'ghi')
5. Now click the 'abc' option with the mouse.
The change event is never received, and the "value is:" text never changes.
I have found that the event wrapping function created by Event.createWrapper() is never being called on step 5. I have no idea why that might be the case.
I have however noticed that the select button receives a mousedown event.
And unless I come up with a clean
-
Andrew Dupont April 14th, 2008 @ 02:38 AM
- → State changed from new to open
We'll take a look at this; thanks. With quirks like these it's no wonder why we have
Abstract.TimedObserver.The best way to contribute to Prototype right now is to keep submitting bugs, writing patches, helping out in IRC/on the mailing list, and generally doing cool stuff with the library. That's how one accrues Karma Points.
-
John-David Dalton April 15th, 2008 @ 04:10 AM
related to "[PATCH] Prototype's EventObserver fires only once when observing radio buttons"
-
Juriy Zaytsev April 16th, 2008 @ 06:12 AM
I can't reproduce this no matter what I try : )
Click, key arrows, etc. all work seamlessly.
FF2/Mac
-
John-David Dalton April 16th, 2008 @ 07:07 AM
I could not repeat this either :(. If you don't actually change the value then it won't alert (ex: if the default item is "abc" and you highlight the other items but don't select them and then select "abc" again, then no change has occured and no alert should fire.
In firefox you can select another item with the arrow keys but the onchange event isn't registered until after the select box loses focus (I don't think that is a bug).
I tested this on:
Mac: Safari 2.4, Safari 3.1, Firefox 2.0.0.2, Firefox 2.0.0.12
Windows: Safari 3.1, Firefox 2.0.0.13
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stric..."> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Select Test</title> <script type="text/javascript" src="prototype.js"></script> <script> document.observe('dom:loaded', function(){ new Form.Element.EventObserver('test1', function(){ alert(this.getValue())}); new Form.Element.EventObserver('test2', function(){ alert(this.getValue())}); new Form.Element.EventObserver('test3', function(){ alert(this.getValue())}); }); </script> </head> <body> <form> <select id="test1"> <option value="1">abc</option> <option value="2">def</option> <option value="3">ghi</option> <option value="4">jkl</option> </select> <select id="test2" type="select-one"> <option value="1">abc</option> <option value="2">def</option> <option value="3">ghi</option> <option value="4">jkl</option> </select> <select id="test3" type="select-multiple"> <option value="1">abc</option> <option value="2">def</option> <option value="3">ghi</option> <option value="4">jkl</option> </select> </form> </body> </html> -

Scott Hyndman April 16th, 2008 @ 01:54 PM
I wasn't testing with alerts because they force focus loss, but let me give that a go.
Did you give my test a try with the instructions (in my second try)?
I just woke up but I'll be at work in a couple hours. I'll post back then.
-

Scott Hyndman April 16th, 2008 @ 01:55 PM
And by second try I mean second comment. haha. Again, just woke up.
-
John-David Dalton April 16th, 2008 @ 03:38 PM
Yes I did test by your second comments. The alert shouldn't matter because its happening after the "change" you are testing for. I changed the "alert" to "console.log" and viewed the results in Firebug and the Safari javascript console. Still could not reproduce.
-

Scott Hyndman April 16th, 2008 @ 04:44 PM
Alright guys, I didn't understand that the "change" event is fired on blur if the select's value is changed through the keyboard.
Seems a bit odd to me (especially since the select's value actually is changed prior to the blur), but I have verified that you are correct.
-
John-David Dalton April 16th, 2008 @ 07:01 PM
- → Title changed from Abstract.EventObserver does not invoke callback function when selected value changes on select control to [DOC] Using arrow keys, Firefox fires dropdown onchange event after element loses focus, others don't
It is a bit strange, Firefox seems to be the oddball here, IE/Opera/Safari will trigger the change before the element looses focus.
I don't know if this is a bug. I am marking it as a documentation note.
But feel free to change it if you want.
-
Tobie Langel April 16th, 2008 @ 10:06 PM
- → Milestone changed from to Inline documentation
- → State changed from open to doc_bug
- → Title changed from [DOC] Using arrow keys, Firefox fires dropdown onchange event after element loses focus, others don't to Using arrow keys, Firefox fires dropdown onchange event after element loses focus, others don't
-
Tobie Langel April 18th, 2008 @ 01:19 PM
- → State changed from doc_bug to doc
-
John-David Dalton May 29th, 2008 @ 04:42 AM
- → Assigned user changed from to Tobie Langel
-

Reza S November 12th, 2008 @ 10:37 PM
- → Tag changed from to form
For your select box drop down just add the following event: @@@javascript Event.observe(mySelect,'keyup',
function(event) { mySelect.blur(); mySelect.focus(); }.bindAsEventListener(this));
Please Login or create a free account to add a new comment.
You can update this ticket by sending an email to from your email client. (help)
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
The Prototype JavaScript library.
