This isn't a jQuery only question as it has to do with events and order of operation. Consider the following code, which is based on jQuery multiSelect plugin (please post citation if you can find it):
Fiddle with it here
var debug = $('#debug');
var updateLog = function (msg){
debug.prepend(msg + '\n');
};
var title = $('#title').focus();
var container = $('#container');
title.keydown(function(e){
// up or down arrows
if (e.keyCode == 40 || e.keyCode == 38) {
var labels = container.find('label');
var idx_old = labels.index(labels.filter('.hover'));
var idx_new = -1;
if (idx_old < 0) {
container.find('label:first').addClass('hover');
} else if (e.keyCode == 40 && idx_old < labels.length - 1) {
idx_new = idx_old + 1;
} else if (e.keyCode == 38 && idx_old > 0) {
idx_new = idx_old - 1;
}
if (idx_new >= 0) {
jQuery(labels.get(idx_old)).removeClass('hover');
jQuery(labels.get(idx_new)).addClass('hover');
}
return false;
}
// space/return buttons
if (e.keyCode == 13 || e.keyCode == 32) {
var input_obj = container.find('label.hover input:checkbox');
input_obj.click();
return false;
}
});
// When the input is triggered with mouse
container
.find('input:checkbox')
.click(function(){
var cb = $(this);
var class = "checked";
if (cb.prop(class)){
cb.parent('label').addClass(class);
} else {
cb.parent('label').removeClass(class);
}
updateLog( cb.closest('label').text().split(/[\s\n]+/).join(' ') + ': '
+ this.checked + ' , '
+ cb.prop(class));
title.focus();
})
;
Notice the difference in the checkbox value for when you click directly on the checkbox, versus when you select the checkbox with the space/enter key. I believe this is because it's calling click during the keydown event, so the value of the checkbox is not yet changed; whereas if you actually click the input, the mouseup event occurs before the click (?), so the setting is applied.
The multiselect plugin does not call the click event, it has almost duplicate code. I'm curious if it would be better to pass a parameter to the click event (or use a global) to detect if it issued by the keyboard or mouse, or if it is better to just do what the plugin did and have the code inside the keydown function.
Obviously, if the log were after the click() runs, the keydown would return trues, but there are things that happen inside of click that are based on the input's checked status.