Hallo all,
I’m trying to rebuild/imitate another site in Javascript (mostly just to edumacate myself) and I’ve run into something.
I have an absolutely-positioned anchor with an onclick event. If it’s clicked, a hidden <select> appears and opens. The focus() is moved to this select immediately.
I can arrow up and down through the select options, and I can click on any of those options with a mouse and trigger the onclick() event I’ve set on the options (I have also tried with setting the onclick event on the select itself, same problem). Hitting ENTER does not seem to trigger the event though (FF7/Debian for now). I have no idea why, since that should be the normal event in a dropdown select when the ENTER key is hit anyway, as far as I can tell.
Am I wrong in this?
Should I explicitly write an onkeyup and check for the Enter key and add an onclick there? (seems like overkill)
Here is the code I’m working with:
HTML
<label for="refineSelect" id="refine"><span>Refine term:</span> <a href="#void" id="refa"> </a>
<select id="refineSelect" name="refineSelect">
<option value="foo">Foo</option>
<option value="bar">Bar</option>
<optgroup label="-- Try on --">
<option value="amazon">Amazon</option>
<option value="bing">Images - Bing</option>
<option value="google">Images - Google</option>
<option value="maps">Maps</option>
<option value="news">News</option>
<option value="wikipedia">Wikipedia</option>
<option value="youtube">YouTube</option>
</optgroup>
<optgroup label="-- Show all --">
<option value="baz">Baz</option>
<option value="quux">Quux</option>
</optgroup>
</select>
</label>
I originally had the label outside the select and may move it back out; it was originally wrapped to try something else out. I don’t think it matters here but maybe??
The CSS isn’t anything special, the anchor is absolutely positioned and so is the select.
Javascript (currently leaving out the bits that are not part of this function):
(inside Object Foo)
init: function() {
var refineAnchor = document.getElementById('refa'),
s = document.getElementById('refineSelect'),
q = document.getElementById('q');
Basis.addClass(s, 'hidden');
Basis.addEventListener(refineAnchor, 'click', Foo.refineClickListener(s, q));
Basis.addEventListener(s, 'blur', Foo.sBlurListener);
...
},
...
showRefineSelect: function(s, q) {
var opt;
Basis.removeClass(s, 'hidden');
s.size = s.length;
//loop through s's options and add click listeners
for(var i=0; i<s.options.length; i++) {
opt = s.options[i];
opt.onclick = (function(opt,s,q){
return function() {
Foo.submitParams(opt,s,q);
}
})(opt,s,q);
}
s.focus();
},
submitParams: function(opt, s, q) {
alert(q.nodeName + ', value is ' + q.value); //for now, my test to see that click event happened
},
hideRefineSelect: function(s) {
s.size='1';
Basis.addClass(s, 'hidden');
},
...
refineClickListener: function(s, q) {
return function() {
Foo.showRefineSelect(s, q);
};
},
sBlurListener: function(event) {
Foo.hideRefineSelect(this);
}
So, when the anchor gets a click event (works with mouse or Enter keys), the select dropdown appears and focus is automatically moved to it. This all works (so far, not widely tested).
I can arrow around the options, which I want.
I can click an option with the mouse and see the result of my click event that I’ve placed on the options.
I cannot hit Enter and see the result of my click event. I see in my debugger that yes, each option is getting the click event assigned to it.
Before adding click events to the options I had tried the simpler add-click-event-to-select. This hadn’t worked originally which is why I thought maybe I needed to add directly to the options.
Is there something I’m obviously missing here? My brain is in a fog.
Also, I’m doing this partially to better learn Javascript. I don’t care if there’s some 500kb downloadable jQuery whatsit that does it all for me. That defeats the purpose really.
Thanks,
poes