Search code examples
jqueryhtmlcssnavigationarrow-keys

Use Arrow Keys to highlight links in div


I have a type of AutoComplete search that i'm building and I was wondering if there was a way to use the up/down arrow keys to navigate through the results once the result div is shown.

The way it works is if results are returned from the database, populate the HTML of the div with the results and display the div directly under the input box, but I am not able to figure out how to then allow the user to use the arrow keys to navigate the results.

Example of the result HTML is;

<div id="divSearchResults" class="AutocompleteSearchResults cfn_ui_search_searchResults" style="visibility: hidden; left: 979px; top: 29px;">
<span>Open Client360 Household:</span>
<a target="_blank" href="/TestApp/default.aspx?ihhid=1">TestHH1</a>
<a target="_blank" href="/TestApp/default.aspx?ihhid=2">TestHH2</a>
<a target="_blank" href="/TestApp/default.aspx?ihhid=3">TestHH3</a>
</div>

i'd like to be able to have the user navigate with the arrow keys, but trying to do a .focus() on the div once it is visible doesn't allow this. I read some stuff about the tabindex being set, but that didn't seem to work for me either, and I figured since this is just a hidden element that only displays when there is a resultset that it might be more difficult.


Solution

  • Here is an exemple for your case. You were pretty close with .focus()

    Assign a class to your span element on arrow keys down the first time.

    Each time you hit a key, you move the class .selected and the focus up or down with addClass(), removeClass() and focus(). This way, you know the hovered item, and which element will be the next, depending on up/down with next()/prev().

    Finally, if you press UP being on the first element then go to the last one, same for the down event.


    $(document).on("focus", "#inputSerch", function () {
        $("#divSearchResults").fadeIn(50);
    })
    
    document.onkeydown = function (e) {
        switch (e.keyCode) {
    
            case 38:
                moveUp();
                break;
    
            case 40:
                moveDown();
                break;
        }
    };
    
    function moveUp() {
        if($(".selected").length==0){
            $("#divSearchResults span").addClass("selected").focus();
        }
        if ($(".selected").prev("a").length > 0) {
            $(".selected").removeClass("selected").prev("a").addClass("selected").focus();
        } else {
            $(".selected").removeClass("selected");
            $("#divSearchResults a:last-child").addClass("selected").focus();
        }
    
    }
    
    function moveDown() {
        if($(".selected").length==0){
            $("#divSearchResults span").addClass("selected").focus();
        }
        if ($(".selected").next("a").length > 0) {
            $(".selected").removeClass("selected").next("a").addClass("selected").focus();
        } else {
            $(".selected").removeClass("selected");
            $("#divSearchResults span").next().addClass("selected").focus();
        }
    }
    
    $(document).on("blur", ".selected", function () {
        $(this).removeClass("selected");
    });
    

    Live exemple