From 0099809db00ceeb61a6f5d3a62fcd98472398e86 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 28 Jun 2019 15:00:03 +0530 Subject: [PATCH] refactor: Use standard keyboard API for list --- frappe/public/js/frappe/list/list_view.js | 84 ++++++++++++++--------- frappe/public/js/frappe/ui/keyboard.js | 8 ++- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 02808a244e..7bcd814811 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -774,44 +774,62 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { let $input = $row.find('input[type=checkbox]'); $input.click(); }; + let get_list_row_if_focused = () => + list_row_focused() ? $(document.activeElement) : null; - $(document).on('keydown', (e) => { - let { UP, DOWN, ENTER, SPACE } = frappe.ui.keyCode; - let key = frappe.ui.keys.get_key(e); - if (![UP, DOWN, ENTER, SPACE].includes(e.which)) return; - if (!this.page.wrapper.is(':visible')) return; - let $list_row = list_row_focused() ? $(document.activeElement) : null; + let is_current_page = () => this.page.wrapper.is(':visible'); + let is_input_focused = () => $(document.activeElement).is('input'); - if ([UP, DOWN].includes(e.which)) { - e.preventDefault(); - - if (!$list_row) { - focus_first_row(); - } else { - if (key === 'shift+down') { - check_row($list_row); - focus_next(); - } else if (key === 'shift+up') { - check_row($list_row); - focus_prev(); - } else if (key === 'down') { - focus_next(); - } else if (key === 'up') { - focus_prev(); - } - } - return; - } + let handle_navigation = (direction) => { + if (!is_current_page() || is_input_focused()) return false; + let $list_row = get_list_row_if_focused(); if ($list_row) { - e.preventDefault(); - if (key === 'enter') { - $list_row.find('a[data-name]')[0].click(); - } else if (key === 'space') { - check_row($list_row); - } + direction === 'down' ? focus_next() : focus_prev(); + } else { + focus_first_row(); } - }); + } + + frappe.ui.keys.add_shortcut('down', () => { + return handle_navigation('down'); + }, __('Navigate list down'), this.page); + + frappe.ui.keys.add_shortcut('up', () => { + return handle_navigation('up'); + }, __('Navigate list up'), this.page); + + frappe.ui.keys.add_shortcut('shift+down', () => { + if (!is_current_page() || is_input_focused()) return false; + let $list_row = get_list_row_if_focused(); + check_row($list_row); + focus_next(); + }, __('Select multiple list items'), this.page); + + frappe.ui.keys.add_shortcut('shift+up', () => { + if (!is_current_page() || is_input_focused()) return false; + let $list_row = get_list_row_if_focused(); + check_row($list_row); + focus_prev(); + }, __('Select multiple list items'), this.page); + + frappe.ui.keys.add_shortcut('enter', () => { + let $list_row = get_list_row_if_focused(); + if ($list_row) { + $list_row.find('a[data-name]')[0].click(); + return true; + } + return false; + }, __('Open list item'), this.page); + + frappe.ui.keys.add_shortcut('space', () => { + let $list_row = get_list_row_if_focused(); + if ($list_row) { + check_row($list_row); + return true; + } + return false; + }, __('Select list item'), this.page); } setup_filterable() { diff --git a/frappe/public/js/frappe/ui/keyboard.js b/frappe/public/js/frappe/ui/keyboard.js index 47cd9e5681..e04db98a95 100644 --- a/frappe/public/js/frappe/ui/keyboard.js +++ b/frappe/public/js/frappe/ui/keyboard.js @@ -30,8 +30,12 @@ frappe.ui.keys.add_shortcut = (shortcut, action, description, page) => { } frappe.ui.keys.on(shortcut, (e) => { if (!page || page.wrapper.is(':visible')) { - e.preventDefault(); - action(e); + let prevent_default = action(e); + // prevent default if true is explicitly returned + // or nothing returned (undefined) + if (prevent_default || prevent_default === undefined) { + e.preventDefault(); + } } }); let existing_shortcut_index = standard_shortcuts.findIndex(