Intermediate

Обработка событий

Все события, которые срабатывают в приложении на Webix, можно разделить на 3 группы:

  • внутренние события компонентов Webix (onAfterSelect, onChange, onItemClick, и т.д.)
  • глобальные события Webix, которые связаны с работой приложения
  • нативные события DOM (их также можно обработать с помощью Webix).

Основная часть этой статьи описывает внутренние события компонентов Webix. Подробнее о 2 других группах можно узнать по ссылкам из этого списка.

Обработка внутренних событий компонента

У всех компонентов Webix есть внутренние события мыши (onItemClick, onBeforeContextMenu, onMouseMoving, onMouseOut, и т.д.). По каждому из этих компонентов можно кликнуть как правой так и левой кнопкой мыши, и получить определенный ответ.

Другие внутренние события виджета напрямую зависят от его возможностей. Информацию о них можно найти в соответствующем справочнике API каждого компонента.

Существует несколько способов, как привязать обработчик к событию компонента.

Наиболее распространенные способы:

  • через метод attachEvent()
  • через свойство компонента on.

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

  • через свойство ready для компонентов данных
  • через свойство click для кнопок и инпутов
  • через объект data или префикс для событий DataStore и TreeStore
  • через объект свойства scheme для компонентов данных (для событий, связанных с загрузкой данных)
  • через специальные свойства для обработки событий мыши (onClick, onContext, onDblClick, onMouseMove).

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

Привязка обработчиков через метод attachEvent()

Метод attachEvent() принимает 2 параметра - название внутреннего события компонента и функцию для обработки этого события (обработчик):

$$("element_id").attachEvent("onSomeEvent", function(){/* логика обработчика */});

Названия событий не чувствительны к регистру.

Кнопка свернет все дочерние элементы древовидной таблицы

var myEvent = $$("button_id").attachEvent("onItemClick", function(){
    $$("dtree").closeAll();
});

Вы также можете отвязать нужное событие от компонента с помощью метода detachEvent():

$$("button_id").detachEvent(myEvent);

Привязка обработчиков через конструктор виджета

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

  • on - объект этого свойства позволяет задать обработчик для любого события компонента
  • ready - функция выполнится после полной загрузки компонента (после инициализации и загрузки данных, если они есть)
  • click - функция выполнится после клика по компоненту. Работает для некоторых контролов формы (button, checkbox и т.д.). Функция принимает 2 параметра:
    • id (string, number) - ID контрола,
    • event (object) - событие мыши (MouseEvent).
webix.ui({
    rows: [
        {
            view: "button",
            click: function(){ }
        },
        {
            view: "list",
            data: [ ],
            ready: function(){ }
        },
        {
            view: "list",
            on: {
                onItemClick: function(id){ 
                    alert("You have clicked on an item with id="+id); 
                }
            }
        }
    ]
});

Related sample:  Attaching Functions in the Constructor

Вы можете создать обработчик за пределами конструктора webix.ui() и привязать его к любому событию через свойство компонента on. В объекте этого свойства необходимо указать название нужного события и присвоить ему соответствующий обработчик:

function select_first(){
    $$("list").select($$("list").getFirstId();)
};
 
webix.ui({
    view: "button",
    on: { 
        "onItemClick": select_first
    }
});

Related sample:  Creating a Custom Table

Свойство click позволяет задать обработчик для события клика по кнопке:

function close_tree(){/* ... */}; 
 
{ 
    view: "button", 
    id: "sample_button", 
    value: "Close", 
    width: 100, 
    click: close_tree 
}

Обработчики для DataStore и TreeStore

Компоненты данных наследуют методы от модулей DataStore и TreeStore. В отличие от методов, их события не наследуются. Чтобы добавить обработчики для таких событий, необходимо использовать объект data:

view.data.attachEvent("onParse", function(driver, data){
   // логика обработчика
});

Задать обработчик для таких событий можно:

  • через префикс "data->" в самом обработчике:
datatable.attachEvent("data->onParse", function(driver, data){
    // логика обработчика 
});
  • через префикс "data->" в объекте свойства on:
view: "datatable",
on: {
    "data->onStoreUpdated": function(){
        // логика обработчика
    }
}

Related sample:  Datatable: Index Column

Привязка обработчиков через свойство scheme

Свойство scheme у компонентов данных позволяет изменить стандартный шаблон обработки данных этих компонентов.

Для примера, в объекте свойства scheme можно задать специальный ключ $init и присвоить ему определенную функцию. Эта функция будет выполняться каждый раз при загрузке/перезагрузке данных в компонент, а также при вызове метода add.

webix.ui({
    view: "list",
    scheme: {
        $init: function(obj){/* ... */},
        $update: function(obj){/* ... */}
   }
});

Related sample:  Horizontal List

Подробнее о схемах обработки данных можно узнать здесь.

Привязка обработчиков к событиям мыши через специальные свойства

Такие свойства являются парными и включают в себя следующие:

  • onClick и on_click для обработки события клика
  • onContext и on_context для обработки события клика правой кнопкой мыши
  • onDblClick и on_dblclick для обработки события двойного клика
  • onMouseMove и on_mouse_move для обработки события, когда указатель мыши находится над компонентом (или его элементом).

С помощью этих свойств можно задать обработчики событий мыши (клик, двойной клик, и т.д.) для элементов с определенным css классом. Вы также можете изменить стандартное поведение таких событий.

Давайте посмотрим, как задать обработчик с помощью свойств onClick и on_click.

1. Свойство on_click позволяет переопределить поведение по умолчанию для клика уже после инициализации компонента.

Привязка обработчика через свойство on_click:

grid = webix.ui({
    view: "datatable",
    columns: [
        { 
            id: "", 
            template: "<input type='button' class='delbtn' value='Delete'>" 
        },
        { id: "title", /* ... */ }
    ],
    on: {
        "onItemClick": function(){/* ... */} // поведение клика по умолчанию
    },
    select: true
});
 
grid.on_click.delbtn = function(e, id, trg){
    webix.message("Delete row: "+id);
    return false; // блокирует поведение клика по умолчанию
};

Related sample:  Datatable: Custom Handler

В ячейках одного из столбцов таблицы находятся HTML шаблоны с кнопкой, которой присвоен css класс 'delbtn'. Для клика по любой из ячеек таблицы, включая и те что с кнопкой, задано поведение по умолчанию. При клике по самой кнопке, стандартное поведение будет перекрываться обработчиком, который задается через ее css класс 'delbtn'.

2. Свойство onClick позволяет переопределить стандартное поведение клика по элементу с css классом прямо в конструкторе компонента.

webix.ui({
    view: "list", 
    template: "#votes# <span class='info'>Details</span>",
    select: "multiselect",
    onClick: {
        info: function(e, id){
            webix.message(this.item(id).title);
            return false; // блокирует поведение клика по умолчанию
        }
    }
});

При клике по любой записи с css классом info, будет отображаться определенное сообщение. Стандартные события будут заблокированы.

Если заданный через свойство onClick обработчик вернет false, то виджет заблокирует все последующие события, связанные с кликом по выбранному элементу: onBeforeSelect, onAfterSelect, onSelectChange, onItemClick. Чтобы увидеть список всех заблокированных событий, вам необходимо подключить режим отладки библиотеки Webix.

Related sample:  List: Event Handlers

Такой же подход работает и для других парных свойств.

Перенос событий от одного компонента к другому

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

Для этого необходимо вызвать метод mapEvent и передать ему соответствующий объект с маршрутом, где маршрут - это пара “событие: компонент”:

webix.ui({
    rows:[
        { view: "list", id: "list1", data: list_data, 
            on: {
                onItemClick: getItemValue
            }
        },
        { view: "list", id: "list2", data: list_data }
    ]
});
// названия событий нужно указывать в нижнем регистре
$$("list2").mapEvent({onitemclick: $$("list1")});

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

function getItemValue(id){
    var obj = this.$eventSource || this;
    var value = obj.getItem(id).value;
    webix.message("List: "+obj.config.id+", clicked: "+id);         
}

Учитывайте, что если нужно получить доступ к объекту, для которого обработчик вызывается в текущий момент времени, вы можете использовать свойство $eventSource. Ключевое слово this всегда указывает на объект, к которому обработчик был привязан изначально.

Обработка событий дочерних элементов виджета

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

Например, вам необходимо привязать событие, которое будет срабатывать каждый раз при клике по элементу списка и выполнять определенные действия с его данными.

$$("mylist").attachEvent("onAfterSelect", function(id){
    alert(this.item(id).title);
});

Related sample:  Sizing and Events

Блокировка событий

События можно разделить на 2 группы:

  • события, результат которых не влияет на работу всего приложения
  • события, результат которых может повлиять на работу всего приложения. Если в названии события есть слово "before", выполнение последующих действий будет зависеть от значения (true или false) которое вернет его обработчик.

Функция возвращает *false* - выбор элемента (select) заблокирован

$$("my_list").attachEvent("onBeforeSelect", function(){ return false; })

Чтобы временно заблокировать все события компонента, можно воспользоваться его методом blockEvent(). Чтобы разблокировать эти события, необходимо вызвать обратный метод unblockEvent().

$$("component_id").blockEvent();
 
$$("component_id").unblockEvent();

Отсрочка событий

По умолчанию, событие срабатывает через 500 мс после вызова. Для таких событий как onMouseMove и onMouseOut вы можете отсрочить ответ сервера на нужное вам время (в миллисекундах):

webix.ui({
    view: "menu",
    mouseEventDelay: 100
});

События клавиатуры

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

  • onKeyPress - срабатывает при нажатии клавиш с определенными кодами
  • onEditKeyPress - то же самое, но для открытого редактора
  • onTimedKeyPress - выполняет указанные действия после нажатия.

В этом примере показано, как работает событие onTimedKeyPress при фильтрации данных в текстовом поле виджета List:

$$("list_input").attachEvent("onTimedKeyPress",function(){ 
    var value = this.getValue().toLowerCase();
    $$("list").filter(function(obj){
        return obj.title.toLowerCase().indexOf(value)==0;
    });
});
// "list_input" - это ID инпута "text"

Related sample:  List: Filtering

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

Глобальные события Webix

Глобальные события Webix не привязаны к работе конкретных компонентов. Их можно применять для всего приложения (клики, события касания, запросы на сервер и т.д.). Некоторые из этих событий дублируют нативные события DOM.

Чтобы привязать глобальные события, необходимо использовать объект webix:

webix.attachEvent("onRotate", function(mode){
    // логика обработчика
});

События, которые связаны с компонентами Webix

  • onDataTable (config, obj) - срабатывает до того, как компонент datatable будет отрисован на странице
  • onEditEnd - срабатывает в момент закрытия всплывающего редактора (date, color, richselect) в любом из компонентов на странице. Смотрите статью о редакторах
  • onLiveValidation (editor, result, obj, value) - срабатывает в момент начала редактирования компонента, если активирована опция live validation
  • onSyncUnknown (obj, source, filter) - срабатывает при попытке синхронизировать данные компонента с коллекцией, которая не относится к Webix
  • onReconstruct (obj) - срабатывает при изменении лейаута приложения (когда некоторые его компоненты удалены, добавлены или изменены). Смотрите статью о динамических изменениях UI
  • onLayoutResize (cells) - срабатывает при изменении размера лейаута (не путайте с окном браузера).

Общие события страницы

  • onClick (e) -срабатывает при одинарном или двойном клике в любой части приложения
  • onFocusChange (newf, oldf) - срабатывает при смене фокуса внутри приложения. В качестве параметров принимает два объекта Webix (элемент в фокусе и его предшественник) или null, если элемент в фокусе не является объектом Webix
  • onReady - срабатывает параллельно с событием onload глобального объекта window
  • unload - срабатывает параллельно с событием unload глобального объекта window.

Тач-события страницы

  • onRotate (orientation) - срабатывает при вращении экрана
  • onAfterScroll (pos) - срабатывает при прокрутке компонентов Webix
  • onTouchStart (context) - срабатывает в начале касания
  • onLongTouch (context) - срабатывает при продолжительном касании
  • onTouchEnd (start_context, current_context) - срабатывает при завершении касания
  • onTouchMove (start_context, current_context) - срабатывает при перемещении касания
  • onSwipeX (start_context, current_context) - срабатывает при горизонтальном свайпе
  • onSwipeY (start_context, current_context) - срабатывает при вертикальном свайпе.

Более подробную информацию о тач-событиях вы найдете в соответствующей статье документации.

События, связанные с запросами на сервер

  • onBeforeAjax (mode, url, data, request, headers, files, promise) - срабатывает при выполнении Ajax запроса
  • onAjaxError (xhr) - срабатывает, если Ajax запрос возвращает ошибку
  • onLoadError (xhr, view) - срабатывает при ошибке загрузки данных в компонент. Смотрите соответствующую статью про управление ошибками при загрузке.

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

События drag-n-drop

Событие onDragMode (signal) срабатывает в начале перетаскивания и при его завершении. Смотрите статью о событиях при перетаскивании.

Обработчики для нативных событий DOM

С помощью методов event() и eventRemove() библиотеки Webix, можно привязать обработчики к нативным событиям DOM. Эти методы нужно вызывать через специальный объект webix:

var eventId = webix.event("divId", "click", function(e){
    do_something();
});
 
webix.eventRemove(eventId);

Комментарии:

  • divID - ID нужного HTML элемента, к которому необходимо привязать событие
  • click - название события (необходимо указывать без префикса on)
  • handler - обработчик события (аргумент e указывает на объект нативного события)
  • context (optional) - дополнительные настройки:
    • bind (object) - объект, на который ссылается ключевое слово this
    • capture (boolean) - флаг, который указывает на стадию (перехват или всплытие), при которой событие должно быть перехвачено.
      По умолчанию false
    • id (string) - ID обработчика событий (если не указано, виджет генерирует его автоматически).
Наверх