http://jsfiddle.net/rFEER/
<select id="users"> <option value="1">jack</option> <option value="2">brill</option> <option value="3">antony</option> </select>
js:
$("#users").change(function(){ alert($(this).val()); })
why change event not fired when using (keyup/keydown) until mouse is clicked
There are three different keyboard events in JavaScript: keydown : Keydown happens when the key is pressed down, and auto repeats if the key is pressed down for long. keypress : This event is fired when an alphabetic, numeric, or punctuation key is pressed down. keyup : Keyup happens when the key is released.
The keydown event is fired when a key is pressed. Unlike the keypress event, the keydown event is fired for all keys, regardless of whether they produce a character value.
The keypress event is fired when a key that produces a character value is pressed down. Examples of keys that produce a character value are alphabetic, numeric, and punctuation keys. Examples of keys that don't produce a character value are modifier keys such as Alt , Shift , Ctrl , or Meta .
why change event not fired when using (keyup/keydown) until mouse is clicked
It also fires when focus leaves the select
. That's just how the change
event works.
If you want proactive notification, you have to watch for change
and keydown
(at least, you may want click
as well) and handle the case of getting an event when the value hasn't actually changed, and you have to handle the fact that some of those events (keydown
, for instance) are fired before the value is changed, so you have to wait a moment before processing the event. Or see SpYk3HH's answer which uses keyup
instead — that will be less proactive (not updating until key release, which could be desireable), but then you don't need the delay (setTimeout
) my code below has.
Example (live copy):
HTML (I took the liberty of changing the values so it was clearer which went with each name):
<select id="users"> <option value="j">jack</option> <option value="b">brill</option> <option value="a">antony</option> </select>
JavaScript:
$("#users").bind("keydown change", function(){ var box = $(this); setTimeout(function() { display(box.val()); }, 0); });
Note in 2016: bind
has largely been replaced with on
. In the above it you'd literally just replace "bind" with "on".
Try changing
$("#users").change(function(){
to
$("#users").bind('change keyup', function(e) {
that should bound yyour function for both, onchange event and when down or up arrow key is pressed
note, you could also use keydown, but it may not preform as expected as your code will run before the select change is made
And in case you want an infinate scrolling Select box, i have a nifty little func i wrote that so far, for me at least, works perfect and can be assigned all on its own without affecting other keyup actions, of course, and with intent on our sight, this is ment to work on the keyup, and so you still have to actually press the arrow key over and over, but it will continue to loop non stop through all options. Although, im pretty sure it'll work with keydown too, but we dont use it that way, so i've not tested it. Again, keydown, may not perform as intended, especially if the select only has 2 or 3 options.
function selectInfinateScroll() { if ($(this).data("lastSelected")) { if ($(this).data("lastSelected")[0] == $(this).children("option:selected")[0]) { if ($(this).children("option:selected").index() == 0) { $(this).children("option:selected").prop("selected", false); $(this).children("option:last-child").prop("selected", true).change(); } else { $(this).children("option:selected").prop("selected", false); $(this).children("option:first-child").prop("selected", true).change(); }; }; }; $(this).data("lastSelected", $(this).children("option:selected")); } $(function() { // Enable 'Scrolling Through' on Select Boxes $("select").keyup(selectInfinateScroll); });
I'm leaving the original answer, as it uses an alternate method that may be more useful to some. However, I have come up with both a shorter function that works on "keydown" and a jQuery plugin using said function that allows user to "hold down" and arrow key and still sort through options infinitely!
First, the new function
function keydownInfiniteSelect(e) { var eKey = e.which || e.key, selected = $(this).find("option:selected"); if (eKey == 38 && selected.is(":first-child")) { // up arro $(this).find("option").last().prop("selected", true); // set value to last option $(this).change(); // ensure select triggers change do to return false return false; // keeps select from skipping to second last option } else if (eKey == 40 && selected.is(":last-child")) { // down arro $(this).val($(this).find("option").first().val()); // set value to first option $(this).change(); // ensure select triggers change return false; // keeps select from skipping to second option } }
Use like: $("select").keydown(keydownInfiniteSelect);
And the jQuery Plugin Style!
(function($){$.infiniteSelect||($.extend({infiniteSelect:function(b){return b.each(function(){$(this).data("infiniteSelect")||($.fn.on?$(this).on("keydown",$.infiniteSelect.methods.keydownInfiniteSelect).data("infiniteSelect",!0):$(this).bind("keydown",$.infiniteSelect.methods.keydownInfiniteSelect).data("infiniteSelect",!0))})}}),$.fn.extend({infiniteSelect:function(){return $.infiniteSelect($(this))}}),$.infiniteSelect.methods={keydownInfiniteSelect:function(b){b=b.which||b.key;var c=$(this).find("option:selected"); if(38==b&&c.is(":first-child"))return $(this).find("option").last().prop("selected",!0),$(this).change(),!1;if(40==b&&c.is(":last-child"))return $(this).val($(this).find("option").first().val()),$(this).change(),!1}})})(jQuery);
Use as $("select").infiniteSelect()
OR $.infiniteSelect("select")
PS. I almost have a Vanilla JavaScript ready for the function except that the "set to last option" part of the method keeps dieing, or going null, or skipping to the second to last. I just can't seem to get it to set correctly. If anyone wants to fix it and update, I'd be much obliged. See HERE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With