From d47a7c6017e70cbb321d62c58a704a58a1646086 Mon Sep 17 00:00:00 2001 From: Carlos Proensa Date: Sat, 9 Mar 2019 19:12:26 +0100 Subject: [PATCH] Projects list js Changes and clean up for the navbar project list dropdown: - When the dropdown is displayed: - Apply focus to the active list element to position the scrollable area over that element. - If the list is empty, apply focus to the searchbox. - Manage key events in the dropdown elements: - When using the list and any key not related to list navigation is pressed (for example, typing a text for searching), switch the focus to the search box for it to receive the input. - When using the searchbox and any key of up, down, pageup, pagedown, is pressed, switch the focus to the list to allow navigating with keyboard. - Escape key in the search box will close the dropdown. - Fix hiding the searchbox when only 10 or less items are displayed. - Code clean-up: - Move all the code related to the navbar projects menu to the same place in the js file. - Rename variables for less probability of collision with other unrelated code. Fixes: #23037, #25594 --- js/common.js | 83 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/js/common.js b/js/common.js index 57f0c2bf4e..7ee365d180 100644 --- a/js/common.js +++ b/js/common.js @@ -48,13 +48,78 @@ $(document).ready( function() { ToggleDiv( t_div ); }); - var options = { - valueNames: [ 'project-link' ] - }; - var list = new List('projects-list', options); - if(list.items.length <= 10) { - $('#projects-list .searchbox').hide(); - } + /** + * Manage the navbar project menu initializacion and events + * for focus and key presses. + */ + + /* initialize the list */ + var projects_list_options = { + valueNames: [ 'project-link' ] + }; + var listprojects = new List('projects-list', projects_list_options); + if( listprojects.items.length <= 10 ) { + $('#projects-list .projects-searchbox').hide(); + } + + /** + * Events to manage focus when displaying the dropdown. + * - Focus on the active item to position the scrollable list on that item. + * - If there is no items to show, focus on the search box. + */ + $(document).on('shown.bs.dropdown', '#dropdown_projects_menu', function() { + var li_active = $(this).find('.dropdown-menu li.active a'); + if( li_active.length ) { + li_active.focus(); + } else { + $('#projects-list .search').focus(); + } + }); + + /** + * When pressing a key in the search box, targeted at navigating the list, + * switch focus to the list. + * When pressing Escape, close the dropdown. + */ + $('#projects-list .search').keydown( function(event){ + switch (event.key) { + case 'ArrowDown': + case 'ArrowUp': + case 'Down': + case 'Up': + case 'PageDown': + case 'PageUp': + var list = $('#projects-list .list'); + if( list.find('li.active').length ) { + list.find('li.active a').focus(); + } else { + list.find('li a').first().focus(); + } + break; + case 'Escape': + $('#dropdown_projects_menu').removeClass('open'); + } + }); + + /** + * When pressing a key in the list, which is not targeted at navigating the list, + * for example, typing a string, toggle focus to the search box. + */ + $('#projects-list .list').keydown( function(event){ + switch (event.key) { + case 'Enter': + case 'ArrowDown': + case 'ArrowUp': + case 'Down': + case 'Up': + case 'PageDown': + case 'PageUp': + case 'Home': + case 'End': + return; + } + $('#projects-list .search').focus(); + }); $('.widget-box').on('shown.ace.widget' , function(event) { var t_id = $(this).attr('id'); @@ -461,10 +526,6 @@ $(document).ready( function() { } }); - $(document).on('shown.bs.dropdown', '#dropdown_projects_menu', function() { - $(this).find(".dropdown-menu li.active a").focus(); - }); - /** * Manage visiblity on hover trigger objects */