Sunday, June 2, 2024
 Popular · Latest · Hot · Upcoming
180
rated 0 times [  186] [ 6]  / answers: 1 / hits: 20784  / 9 Years ago, wed, november 18, 2015, 12:00:00

I'm trying to figure out a way to create an extremely basic autocomplete without 3rd parties dependencies. so far I've gotten to populate a list of results with an ajax call, and with mouse onclick events on each li the script completes the fields as supposed.

what I need to implement is an up/down/enter keys navigation system based on pure js, and after hours spent searching I gave up. this fiddle explains quite perfectly my situation, with the difference that it does require jQuery.



I'd rather not paste any of my own code here as the final aim is learning the process, but since I'm linking to jsfiddle I'm required to so here's the fiddle.



fiddle HTML:



<div id=MainMenu>
<ul>
<li class=active><a href=#>PATIENT TEST</a></li>
<li><a href=#>QC TEST</a></li>
<li><a href=#>REVIEW RESULTS</a></li>
<li><a href=#>OTHER</a></li>
</ul>
</div>

<a href=# id=btnUp>Up</a>
<a href=# id=btnDown>Down</a>


fiddle JS:



$(document).ready(function () {
$('#btnDown').click(function () {
var $current = $('#MainMenu ul li.active');
if ($current.next().length > 0) {
$('#MainMenu ul li').removeClass('active');
$current.next().addClass('active');
}
});

$('#btnUp').click(function () {
var $current = $('#MainMenu ul li.active');
if ($current.prev().length > 0) {
$('#MainMenu ul li').removeClass('active');
$current.prev().addClass('active');
}
});

$(window).keyup(function (e) {
var $current = $('#MainMenu ul li.active');
var $next;

if (e.keyCode == 38) {
$next = $current.prev();
} else if (e.keyCode == 40) {
$next = $current.next();
}

if ($next.length > 0) {
$('#MainMenu ul li').removeClass('active');
$next.addClass('active');
}
});

});


thanks a lot in advance to anyone willing to point me in the right direction.


More From » html

 Answers
11

This turned out to be simpler than I expected, and I've came up with the following code which appearently does the job quite well.



Things to take in account are:




  • the HTML attribute 'tabindex' must be specified on each element for the .focus() to be applied

  • to have a ENTER->submit feeling, you MUST target a link element within the li (still, I'm achieving this with onclick events not included here)

  • this works with an extremely simple list structure, so far I haven't tested it with nested dropdown menus

  • Note: this is most likely not suitable for a copy/paste situation, but as far as I can tell this method is procedurally currect, and can get you started developing more complex solutions



This is the basic HTML:



<input type=text name=main_input id=input />
<ul id=list>
<li class=listElement><a href=# tabindex=1>li content</a></li>
<li class=listElement><a href=# tabindex=1>li content</a></li>
<li class=listElement><a href=# tabindex=1>li content</a></li>
</ul>


And here's the JS function, triggered when the list above is populated and shown:



    function scrollList() {
var list = document.getElementById('list'); // targets the <ul>
var first = list.firstChild; // targets the first <li>
var maininput = document.getElementById('input'); // targets the input, which triggers the functions populating the list
document.onkeydown = function(e) { // listen to keyboard events
switch (e.keyCode) {
case 38: // if the UP key is pressed
if (document.activeElement == (maininput || first)) { break; } // stop the script if the focus is on the input or first element
else { document.activeElement.parentNode.previousSibling.firstChild.focus(); } // select the element before the current, and focus it
break;
case 40: // if the DOWN key is pressed
if (document.activeElement == maininput) { first.firstChild.focus(); } // if the currently focused element is the main input --> focus the first <li>
else { document.activeElement.parentNode.nextSibling.firstChild.focus(); } // target the currently focused element -> <a>, go up a node -> <li>, select the next node, go down a node and focus it
break;
}
}
}


Apologies in advance for the kinda chaotic layout of the code, the function I came up with is a bit more complex and I've stripped out most of it for explaination purposes.



Needless to say, I'm looking forward any comment about the solution above, in regard of errors, improvements or known compatibility issues.


[#64353] Monday, November 16, 2015, 9 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
odaliss

Total Points: 342
Total Questions: 102
Total Answers: 98

Location: The Bahamas
Member since Tue, Apr 27, 2021
3 Years ago
;