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
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);
});
UPDATED!
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")
jsFiddle of Plugin Minified
Uncut Plugin Fiddle
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
That is the normal behaviour ...
Quoting the w3c specs
change
The change event occurs when a control loses the input focus and its value has been modified since gaining focus. This event is valid for INPUT, SELECT, and TEXTAREA. element.
Using the answers above I was able to get the behaviour I needed using:
$( "select" ).bind('keyup', function(e) {
$( '#' + e.target.id ).trigger('change');
});
$("#users").bind('change keyup', function(e) {
was enough
/*After having been searching for hours i wrote my own. */
<script>
jQuery(document).ready(function () {
/*********** SELECT PLZ ****************/
/*********** SELECT PLZ ****************/
/*********** SELECT PLZ ****************/
jQuery('.dropedZip').html('' +
'<select name="theName" id="theID" size="4" style="width: 184px" >' +
'<option value="A">Choice A</option>' +
'<option value="B">Choice B</option>' +
'<option value="C">Choice C</option>' +
'<option value="D">Choice D</option>' +
'</select>');
var nextOptValue = 0;
var prevOptValue = 0;
jQuery('#prop').keydown(function (e) {
var key = e.which;
if(key==13){
var currOptValue = jQuery('select#theID > option:selected').val();// CURRENT
alert('ausgesucht: '+currOptValue);
}
/* UP */
if(key==38){
var currOptValue = jQuery('select#theID > option:selected').val();// CURRENT
if(currOptValue!=undefined){// CURRENT != undefined ?
prevOptValue = jQuery('select#theID > option:selected').prev('option').val();// PREV
if(prevOptValue!=undefined){// PREV != undefined ?
jQuery('select#theID > option:selected').removeAttr('selected');// REMOVE CURRENT
jQuery('select#theID > option[value='+prevOptValue+']').prop('selected',true);// SET PREV
jQuery('input#prop').val(prevOptValue);// SET INPUT VALUE : OTHER
}
}
}
/* DOWN */
if(key==40){
if(jQuery('select#theID > option:selected').val()==undefined){// NULL
nextOptValue = jQuery('select#theID > option:first').val();// FIRST
jQuery('select#theID > option[value='+nextOptValue+']').prop('selected',true);// SET FIRST
jQuery('input#prop').val(nextOptValue);// SET INPUT VALUE : FIRST
}else{
nextOptValue = jQuery('select#theID > option:selected').next('option').val();// NEXT
jQuery('select#theID > option:selected').removeAttr('selected');// REMOVE FIRST
jQuery('select#theID > option[value='+nextOptValue+']').prop('selected',true);// SET NEXT
jQuery('input#prop').val(nextOptValue);// SET INPUT VALUE : OTHER
}
}
});
/*********** SELECT PLZ ****************/
/*********** SELECT PLZ ****************/
/*********** SELECT PLZ ****************/
});
</script>
<input id="prop" type="text">
<div class="dropedZip"></div>