user_dropdown_v1.js 3.28 KB
Newer Older
1 2 3 4 5 6
/**
 * Keyboard support for the user dropdown on legacy pages.
 *
 * Note: this is not used for Pattern Library or Bootstrap pages.
 */

7
$(document).ready(function() {
8
    'use strict';
9

10
    // define variables for code legibility
11 12
    var $dropdownMenuToggle = $('.user-dropdown');
    var $dropdownMenu = $('.user-dropdown-menu');
13
    var menuItems = $dropdownMenu.find('.dropdown-menuitem');
14

15 16 17 18 19 20 21 22 23
    var keyCodes = {
        leftArrow: 37,
        upArrow: 38,
        rightArrow: 39,
        downArrow: 40,
        tab: 9,
        escape: 27,
        space: 32
    };
24 25


26 27 28 29 30 31 32 33 34
    // bind menu toggle click for later use
    $dropdownMenuToggle.toggle(function() {
        $dropdownMenu.addClass('expanded').find('.dropdown-menuitem').first()
            .focus();
        $dropdownMenuToggle.addClass('active').attr('aria-expanded', 'true');
    }, function() {
        $dropdownMenu.removeClass('expanded');
        $dropdownMenuToggle.removeClass('active').attr('aria-expanded', 'false').focus();
    });
35

36 37 38 39 40 41 42 43
    // catch keypresses when focused on $dropdownMenuToggle (we only care about spacebar keypresses here)
    $dropdownMenuToggle.on('keydown', function(event) {
        // if space key pressed
        if (event.which === keyCodes.space) {
            $dropdownMenuToggle.click();
            event.preventDefault();
        }
    });
44

45 46 47
    function catchKeyPress(object, event) {
        // get currently focused item
        var focusedItem = jQuery(':focus');
48

49 50
        // get the number of focusable items
        var numberOfMenuItems = menuItems.length;
51

52 53
        // get the index of the currently focused item
        var focusedItemIndex = menuItems.index(focusedItem);
54

55 56
        // var to store next focused item index
        var itemToFocusIndex;
57

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
        // if space key pressed
        if (event.which === keyCodes.space) {
            $dropdownMenuToggle.click();
            event.preventDefault();
        }

        // if escape key pressed
        if (event.which === keyCodes.escape) {
            $dropdownMenuToggle.click();
            event.preventDefault();
        }

        // if up arrow key pressed or shift+tab else down key or tab is pressed
        if (event.which === keyCodes.upArrow || event.which === keyCodes.leftArrow ||
            (event.which === keyCodes.tab && event.shiftKey)) {
            // if first item go to last
            if (focusedItemIndex === 0) {
                menuItems.last().focus();
            } else {
                itemToFocusIndex = focusedItemIndex - 1;
                menuItems.get(itemToFocusIndex).focus();
            }
            event.preventDefault();
        } else if (event.which === keyCodes.downArrow || event.which === keyCodes.rightArrow ||
            event.which === keyCodes.tab) {
            // if last item go to first
            if (focusedItemIndex === numberOfMenuItems - 1) {
                menuItems.first().focus();
            } else {
                itemToFocusIndex = focusedItemIndex + 1;
                menuItems.get(itemToFocusIndex).focus();
89
            }
90
            event.preventDefault();
91
        }
92
    }
93

94 95 96 97
    // catch keypresses when inside $dropdownMenu
    // (we want to catch spacebar; escape; up arrow or shift+tab; and down arrow or tab)
    $dropdownMenu.on('keydown', function(event) {
        catchKeyPress($(this), event);
98
    });
99
});