tags:

views:

239

answers:

2

I have a load of nested <ul>'s and <li>'s and I would like to be able to have a hover / selected class on an <li>, and use the keyboard up and down buttons to select up and down on the <li>s.. however they are nested and need to jump across <ul>s if necessary.

For instance:

<ul>
    <li class='cat'>
        cat 1
        <ul>
            <li class='hover'>item 1</li>
            <li>item 2</li>
            <li>item 3</li>
            <li>item 4</li>
        </ul>
    </li>
    <li class='cat'>
        cat 2
        <ul>
            <li>item 5</li>
            <li>item 6</li>
            <li>item 7</li>
            <li>item 8</li>
        </ul>
        <ul class='subcat'>
            <li class='cat'>
                Cat 3
                <ul>
                    <li>item 9</li>
                    <li>item 10</li>
                    <li>item 11</li>
                    <li>item 12</li>
                </ul>
            </li>
        </ul>
    </li>
    <li class='cat'>
        cat 4
        <ul>
            <li>item 13</li>
            <li>item 14</li>
            <li>item 15</li>
            <li>item 16</li>
        </ul>
    </li>
</ul>

As I press the down key I wish the items to be selected in numerical order (they do not have numerical order IDs and sometimes some of them are hidden so they should be ignored. But it needs to go to the next <li> that isn't a category and set that as hover.

A: 

Have you tried anything yourself yet?

Without a specific solution, here are a few things to get you going.

1) Bind the keypress event (e.g. to the document)

$(document).keydown(MyKeyupFunc);

2) Capture the up/down keypress:

function MyKeyupFunc(event){

    switch (event.keyCode) {
        case 38: //keyup
            //key down code
            break;
        case 40: //keydown
            //key up code
            break;
        default:
            return;
    }

    //stop event 
    event.preventDefault();
    event.stopPropagation();
    if ($.browser.msie) {
        event.originalEvent.keyCode = 0;
        event.originalEvent.cancelBubble = true;
        event.originalEvent.returnValue = false;
    }
}

3) The code for your keyup/keydown, will involve looking for what is selected, and what is the next/previous item. You may need to check that an item has the hover class on it as well.

You will need some what of selecting your navigable items, therefore, you will need something for jQuery to be able to select. Suggest adding an empty css class="navigable" to each, and that way you can select all the items subject to keyboard navigation:

var $navListitems = $("li.navigable");

Factoring your visible requirement:

var $navListitems = $("li.navigable:visible");

4) Maybe think about sorting these check out the following link

http://www.wrichards.com/blog/2009/02/jquery-sorting-elements/

This is a starter, anyway. I can think of lots more you'll need to do, but I think it will be an adventure for you to try yourself.

When you have specific questions, I'm sure folk will be happy to help if you post back to the forum :-)

James Wiseman
A: 

You can do this with pure HTML if you use radio buttons.

<ul>
    <li class='cat'>cat 1
        <ul>
        <li><input type='radio' name='n' id='n1'><label for='n1'>item 1</label></input></li>
        <li><input type='radio' name='n' id='n2'><label for='n2'>item 2</label></input></li>
        <li><input type='radio' name='n' id='n3'><label for='n3'>item 3</label></input></li>
        <li><input type='radio' name='n' id='n4'><label for='n4'>item 4</label></input></li>
        </ul>
    </li>
    <li class='cat'>cat 2
        <ul>
        <ul>
        <li><input type='radio' name='n' id='n5'><label for='n5'>item 5</label></input></li>
        <li><input type='radio' name='n' id='n6'><label for='n6'>item 6</label></input></li>
        <li><input type='radio' name='n' id='n7'><label for='n7'>item 7</label></input></li>
        <li><input type='radio' name='n' id='n8'><label for='n8'>item 8</label></input></li>
        </ul>
        <ul class='subcat'>
            <li class='cat'>Cat 3
                <ul>
                <li><input type='radio' name='n' id='n9'><label for='n9'>item 9</label></input></li>
                <li><input type='radio' name='n' id='n10'><label for='n10'>item 10</label></input></li>
                <li><input type='radio' name='n' id='n11'><label for='n11'>item 11</label></input></li>
                <li><input type='radio' name='n' id='n12'><label for='n12'>item 12</label></input></li>
                </ul>
            </li>
        </ul>
    </li>
    <li class='cat'>
        cat 4
        <ul>
        <li><input type='radio' name='n' id='n13'><label for='n13'>item 13</label></input></li>
        <li><input type='radio' name='n' id='n14'><label for='n14'>item 14</label></input></li>
        <li><input type='radio' name='n' id='n15'><label for='n15'>item 15</label></input></li>
        <li><input type='radio' name='n' id='n16'><label for='n16'>item 16</label></input></li>
        </ul>
    </li>
</ul>
Anthony Faull