I do not have enough knowledge in JQuery to figure out, where in this code below i’d mistaken. I’m not sure about .live handler. Anyway, this code stops on first <li> with added class ‘selected‘ on keydown event. I want it to check all <li> on each keydown.
Thank you for any constructive comments.
- suggest – input field, on keyup appears autosuggest list,
- result –
<ul id='result'></ul> - selected –
<li>‘s
Script:
$('#suggest').live('keyup keydown', function(event) {
var search = $('#suggest').val();
$.post('search.php', {
search: search
}, function(data) {
$('#dropdown').html(data);
switch (event.which) {
case 40:
var found = 0;
$('#result li').each(function() {
if ($(this).attr("class") == "selected") {
found = 1;
}
});
if (found == 1) {
var sel = $("#result li[class='selected'");
// check if this is a last element in the list
// if so then add selected class to the first element in the list
if (sel.next().text() == '') {
$("#result li:first").addClass("selected");
} else {
sel.next().addClass('selected');
// remove class selected from previous item
sel.removeClass('selected');
}
} else {
$("#result li:first").addClass("selected");
}
break;
case 38:
//bla-bla
break;
}
});
});
A few notes:
.attr("class") ==. If the element has more than one class, or the attribute is poorly formatted, this will never match. jQuery provides.hasClass()for just this purpose.$(this).hasClass('selected').each()to see if one has a class. You can call.hasClass()on the whole group..myclassnot[class="myclass"]. This is for similar reasons as point #1.var sel = $("#result li.selected");sel.next().text() == ''. This will end up callingtext()on an undefined object (because there is none). Instead use.lengthto see if there is/isn’t a next object:sel.next().length == 0if/thenstatement to do the up/down stuff separate from searching.casefor each key, use the same code for both, but modify it slightly depending on whether you have up or down.keyupandkeydownwill cause your up/down keys to fire twice, meaning your user will only be able to step 2 or more items at a time. Either just use one, or only respond to one for the up/down code usingif(event.type == 'keydown') {With all of that, everything seems to work ok:
http://jsfiddle.net/wgQE5/2/
Is there some other behavior you were wanting?