Advanced

События клавиатуры. Фокусировка. Навигация

При создании любого компонента на странице (даже одного), каждый раз происходит инициализация модуля UIManager. Этот модуль делает следующее:

  • следит за тем, какой компонент сейчас в фокусе
  • устанавливает и убирает фокус
  • привязывает события клавиатуры к компонентам, которые сейчас в фокусе
  • запоминает общую структуру компонентов.

Управление фокусом

Методы фокусировки

Для управления фокусом, у Webix контролов (Button, Text, и т.д.), формы и тулбара предусмотрены 2 противоположных метода:

  • focus() - берет компонент в фокус
  • blur() - снимает фокус с компонента.
$$("toolbar").focus(); // устанавливает фокус на тулбаре
$$("toolbar").blur(); // убирает фокус с тулбара
 
$$("form").focus(); // устанавливает фокус на первый фокусируемый элемент формы

Если вызвать метод focus() для формы или тулбара, то в качестве параметра можно передать название необходимого контрола. В этом случае, фокус будет установлен на указанный контрол, а не на форму или тулбар:

$$("form").focus("text1"); 
// устанавливает фокус на контрол text с названием "text1"

У модуля UIManager есть несколько методов, которые принимают ID нужных виджетов:

  • getFocus() - возвращает объект виджета, который сейчас находится в фокусе
  • setFocus(id) - устанавливает фокус на указанный виджет (через его id)
  • hasFocus(id) - проверяет, находится ли фокус на указанном виджете и возвращает соответствующее значение true или false
  • canFocus(id) - проверяет, можно ли установить фокус на указанный виджет. Фокус нельзя установить на невидимые (скрытые) компоненты и их элементы, а также на заблокированные компоненты.

Чтобы установить фокус на компонент данных, необходимо вызвать для него метод setFocus(), а затем применить метод select(), чтобы сделать фокус видимым:

Устанавливаем фокус на виджет с ID "books"

webix.ui({ id: "books", view: "list" });
webix.UIManager.setFocus("books"); // устанавливает фокус
$$("books").select($$("books").getFirstId()); // делает фокус видимым

События фокусировки

У каждого компонента Webix есть пара событий onFocus и onBlur, с помощью которых можно управлять фокусом компонента:

$$("datatable1").attachEvent("onFocus", function(current_view, prev_view){
    // параметр current_view - это таблица
});
 
$$("datatable1").attachEvent("onBlur", function(prev_view){
   // параметр prev_view - это таблица
});

Кроме этих двух событий, у Webix есть глобальное событие onFocusChange, которое срабатывает каждый раз, когда фокус перемещается с одного компонента к другому. Следующий код получает ID компонента на котором находится фокус и выводит его через консоль:

webix.attachEvent("onFocusChange", function(current_view, prev_view){
    console.log("focused: " + (!current_view ? "null" : current_view.config.id));
});

Встроенные события клавиатуры

Виджеты, которые находятся в фокусе, подписаны на события следующих клавиш и их сочетаний:

  • Tab, Tab+Shift - перемещает фокус к следующему/предыдущему кликабельному элементу/инпуту внутри виджета, или переходит к следующему/предыдущему виджету в порядке перемещения по вкладкам.

Информацию о глобальной навигации по вкладкам смотрите в соответствующей части текущей статьи.

Всплывающие окна и сообщения

Компоненты данных

Чтобы активировать горячие клавиши для навигации внутри компонентов данных (datatable и list), необходимо задать их свойству navigation значение true:

Компоненты данных реагируют на нажатие клавиш со стрелками следующим образом:

  • up/left - выбирает предыдущий элемент
  • right/down - выбирает следующий элемент
  • page up - выбирает элемент, у которого индекс равен "текущий индекс+10"
  • page down - выбирает элемент, у которого индекс равен "текущий индекс-10"
  • home - выбирает первый элемент
  • end - выбирает последний элемент.

При нажатии на клавиши со стрелками "left", "right" и "Enter", компоненты c иерархическими данными (например Tree, Treetable и Grouplist) будут реагировать по своему:

  • left - свертывает выбранную ветку
  • right - разворачивает выбранную ветку
  • Enter - свёртывает/разворачивает выбранную ветку (работает для Tree и Treetable).

Если ни один из элементов не выбран, фокус будет установлен на первый видимый элемент виджета.

Редакторы внутри компонентов данных реагируют при нажатии на следующие клавиши:

  • Esc - закрывает редактор без сохранения изменений
  • Enter - сохраняет изменения и закрывает редактор.

Comboboxes

Такие контролы как combo, richselect, multiselect, multicombo, datepicker, daterangepicker и colorpicker подписаны на нажатие следующих клавиш:

  • up/left - выбирает предыдущее значение в соответствующем всплывающем окне контрола. Клавиша “up” не открывает попап с опциями (но работает, если попап уже открыт), а клавиша “left” открывает попап (и работает, если он уже открыт)
  • right/down - выбирает следующее значение в соответствующем всплывающем окне контрола
  • Enter - показывает/прячет выпадающий список опций контрола при установке выбранного значения
  • Esc - прячет выпадающий список опций контрола при установке выбранного значения.

Tabbar и Radio

В глобальный порядок перехода по вкладкам включена только первая вкладка/радиокнопка. Чтобы переключаться между элементами внутри этих контролов, необходимо использовать следующие клавиши:

  • up/left - выбирает следующую вкладку/радиокнопку
  • down/right - выбирает предыдущую вкладку/радиокнопку.

Counter, Slider и RangeSlider

Горячие клавиши для этих контролов активируются только если поле ввода или регулятор слайдера находятся в фокусе:

  • up/right - увеличивает значение контрола на одну единицу
  • down/left - уменьшает значение контрола на одну единицу.

Carousel

Кнопки виджета Carousel можно выделить и они входят в порядок перемещения фокуса по вкладкам. Помимо этого, если иконки виджета находятся в фокусе, они реагируют на нажатие по таким клавишам:

  • left - выбирает следующую иконку и показывает соответствующее изображение
  • right - выбирает предыдущую иконку и показывает соответствующее изображение.

Calendar

  • up/left - выбирает предыдущую дату
  • right/down - выбирает следующую дату
  • page up - выбирает текущее число предыдущего месяца
  • page down - выбирает текущее число следующего месяца
  • home - выбирает первое число месяца
  • end - выбирает последнее число месяца
  • Tab - переходит по кликабельным элементам виджета calendar (кнопки, иконки).

Если дата не выбрана, фокус будет установлен на первое число месяца.

Если calendar отображается в режиме выбора времени, то клавиши со стрелками "left" и "right" позволяют управлять часами, а клавиши со стрелками "up" и "down" - минутами.

Colorboard

  • up/down - выбирает верхнюю/нижнюю ячейку
  • left/right - выбирает левую/правую ячейку
  • home - выбирает первую ячейку
  • end - выбирает последнюю ячейку.

Если ни одна из ячеек не выбрана, фокус будет установлен на первую видимую ячейку.

Toggle и Checkbox

  • Клавиша Enter меняет состояние контрола, который находится в фокусе.

Color Select

  • Tab - перемещает фокус между слайдерами (2 точки) и инпутом
  • up/left/page up - перемещает активный слайдер влево или вверх
  • right/down/page down - перемещает активный слайдер влево или вниз
  • home - перемещает активный слайдер в изначальную позицию (крайняя левая позиция сверху)
  • end - перемещает активный регулятор в крайнюю правую позицию сверху.

Обратите внимание, что если перевести фокус на один из контролов выбора цвета, то:

  • up/left/down/right - перемещает слайдер внутри прямоугольной области для выбора цвета (насыщенность/яркость)
  • page up/page down - перемещает слайдер вдоль линии выбора цвета.

Настройка собственных горячих клавиш

Горячие клавиши для контролов

Вы можете определить собственные горячие клавиши, которые будут вызывать событие onClick. Название клавиши ("enter" или "space") необходимо указывать через свойство hotkey виджета:

{ view: "button", click: doOnClick, hotkey: "enter" }

Related sample:  Hotkeys for Buttons

Функция-обработчик doOnClick будет выполнятся как при клике по самой кнопке, так и при нажатии на клавишу "enter".

Вы можете комбинировать клавиши при помощи знаков “+” или “-”:

{ view: "button", click: doOnClick, hotkey: "enter-shift" }

Учитывайте, что такая опция предусмотрена только для простых контролов (кнопки и инпуты). Для контролов с множественным выбором это не работает.

Создание собственных горячих клавиш

Для создания собственных горячих клавиш, у библиотеки предусмотрен метод addHotKey. Это метод вызывается из объекта UIManager и принимает два обязательных параметра:

  • название клавиши
  • обработчик события.

Вы можете комбинировать клавиши при помощи знаков “+” или “-”.

Вы можете сделать горячие клавиши глобальными. Это значит, что они будут вызывать обработчик независимо от компонента.

webix.UIManager.addHotKey("Ctrl+V", function(){ 
  webix.message("Ctrl+V for any");
});

Чтобы привязать горячую клавишу к определенному экземпляру виджета, необходимо предать его ID в качестве третьего параметра методу addHotKey().

Чтобы привязать горячую клавишу ко всем экземплярам виджета, необходимо передать название этого виджета (вместо ID) в качестве третьего параметра методу addHotKey().

// горячие клавиши для компонента с ID "details"
webix.UIManager.addHotKey("Ctrl+Enter", function(){ 
    console.log("Ctrl+Enter for details"); 
    return false; 
}, $$("details")); // только для компонента list с ID "details"
 
 
// горячие клавиши для всех экземпляров виджета на странице
webix.UIManager.addHotKey("Ctrl+Space", function(){ 
    console.log("Ctrl+Space is detected for list"); 
}, "list");

Related sample:  Basic Use of Editors

Удаление горячих клавиш

Для удаления горячих клавиш, у библиотеки предусмотрен метод removeHotKey. Он принимает название горячей клавиши в качестве обязательного параметра.

// добавляем горячую клавишу
webix.UIManager.addHotKey("Ctrl+Space", function(){ ... }, "list");
 
// удаляем все горячие клавиши с указанным сочетанием
webix.UIManager.removeHotKey("Ctrl+Space");

Вы можете указать обработчик горячей клавиши в качестве второго параметра, чтобы удалить только эту горячую клавишу:

// удаляем горячую клавишу с указанным обработчиком
webix.UIManager.removeHotKey("up", my_function);

Чтобы удалить горячую клавишу из конкретного экземпляра виджета, необходимо указать его ID в качестве третьего параметра.

Чтобы удалить горячую клавишу из всех экземпляров виджета, необходимо указать его название (вместо ID) в качестве третьего параметра:

// удаляем горячую клавишу для компонента с ID "details" 
webix.UIManager.removeHotKey("up", null, $$("details"));
 
// удаляем горячую клавишу для всех экземпляров компонента list на странице
webix.UIManager.removeHotKey("up", null, "list");

Привязка событий клавиатуры

  • onKeyPress (code, ctrl flag, shift flag, native event) - принимает коды клавиш, при нажатии на которые будут выполняться нужные действия
  • onEditKeyPress (code, ctrl flag, shift flag, native event) - повторяет возможности предыдущего события, но, в отличие от него, может применяться к открытому редактору
  • onTimedKeyPress - срабатывает с задержкой и выполняет логику обработчика только после того, как пользователь прекратил вводить данные.

В примере ниже, клавиша Enter открывает соответствующий элемент с ID "details".

Но перед этим, необходимо проверить, чтобы эта клавиша не была связана с клавишами Ctrl, Shift и Alt:

Клавиша "Enter" в действии

$$("books").attachEvent("onKeyPress", function(code, e){
    if (code === 13 && !e.ctrlKey && !e.shiftKey && !e.altKey) {
        $$("details").getParentView().expand("details");
        return false;
    }
});

Для работы с этим событием необходимо знать коды тех клавиш, которые можно использовать в модуле UIManager:

Коды клавиш

  • "enter": 13
  • "tab": 9
  • "esc": 27
  • "escape": 27
  • "up": 38
  • "down": 40
  • "left": 37
  • "right": 39
  • "pgdown": 34
  • "pagedown": 34
  • "pgup": 33
  • "pageup": 33
  • "end": 35
  • "home": 36
  • "delete": 46
  • "backspace": 8
  • "space": 32
  • "meta": 91
  • "win": 91
  • "mac": 91
  • "multiply": 106
  • "add": 107
  • "subtract": 109
  • "decimal": 110
  • "divide": 111
  • "scrollock": 145
  • "pausebreak": 19
  • "numlock": 144
  • "shift": 16
  • "capslock": 20

Глобальная навигация по вкладкам

Логика перемещения вкладок/фокуса

Вы можете перемещаться между элементами приложения при помощи клавиши Tab и сочетания Shift+Tab. Все виджеты и их кликабельные элементы находятся в порядке перехода по вкладкам.

При переходе к виджету, фокус переместится на его активную область. Это может быть выбранный элемент, активная вкладка или радиокнопка, или же целый виджет (например инпут или кнопка). В случае компонентов данных, фокус перейдет к их первому видимому элементу.

Все кликабельные элементы виджета (кнопки, иконки, инпуты и т.д.) также находятся в порядке перехода по вкладкам.

Через методы модуля UIManager можно получить объект следующего/предыдущего виджета в порядке перехода по вкладкам:

  • getNext(id) - получает объект следующего виджета
  • getPrev(id) - получает объект предыдущего виджета
  • getTop(id) - получает объект родительского виджет для всех компонентов.

Все эти методы принимают ID нужного виджета в качестве аргумента.

Давайте возьмем за пример изображение выше и посмотрим, как эти методы будут работать для контрола text с ID "year".

var prev = webix.UIManager.getPrev($$("year")); // возвращает объект поля "title"
var next = webix.UIManager.getNext($$("year")); // возвращает объект поля "rank" 
var top = webix.UIManager.getTop($$("year")); // возвращает объект  "layout"
Наверх