devextreme
Version:
JavaScript/TypeScript Component Suite for Responsive Web Development
104 lines (103 loc) • 4.08 kB
JavaScript
/**
* DevExtreme (esm/__internal/scheduler/appointments/m_appointments_kbn.js)
* Version: 25.2.5
* Build date: Fri Feb 20 2026
*
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
import $ from "../../../core/renderer";
import {
getPublicElement
} from "../../core/m_element";
import eventsEngine from "../../events/core/m_events_engine";
import {
getNextElement,
getPrevElement
} from "./utils/sorted_index_utils";
export class AppointmentsKeyboardNavigation {
constructor(collection) {
this.$focusedItem = null;
this._collection = collection
}
getFocusableItems() {
const appts = this._collection._itemElements().not(".dx-state-disabled");
const collectors = this._collection.$element().find(".dx-scheduler-appointment-collector");
return appts.add(collectors)
}
getFocusableItemBySortedIndex(sortedIndex) {
const $items = this.getFocusableItems();
const itemElement = $items.toArray().filter((itemElement => {
const $item = $(itemElement);
const itemData = this._collection.getAppointmentSettings($item);
return itemData.sortedIndex === sortedIndex
}));
return $(itemElement)
}
focus() {
if (this.$focusedItem) {
const focusedElement = getPublicElement(this.$focusedItem);
this._collection.option("focusedElement", focusedElement);
eventsEngine.trigger(focusedElement, "focus")
}
}
focusInHandler(e) {
this.$focusedItem = $(e.target);
this._collection.option("focusedElement", getPublicElement(this.$focusedItem))
}
focusOutHandler() {
const $item = this.getFocusableItemBySortedIndex(0);
this._collection.option("focusedElement", getPublicElement($item))
}
getSupportedKeys() {
return {
escape: this.escHandler.bind(this),
del: this.delHandler.bind(this),
tab: this.tabHandler.bind(this)
}
}
resetTabIndex($appointment) {
this.getFocusableItems().attr("tabIndex", -1);
$appointment.attr("tabIndex", this._collection.option("tabIndex"))
}
tabHandler(e) {
if (!this.$focusedItem) {
return
}
const $focusableItems = this.getFocusableItems();
let index = this._collection.getAppointmentSettings(this.$focusedItem).sortedIndex;
let $nextAppointment = e.shiftKey ? getPrevElement(index, this._collection.renderedElementsBySortedIndex) : getNextElement(index, this._collection.renderedElementsBySortedIndex);
const lastIndex = $focusableItems.length - 1;
if ($nextAppointment || index > 0 && e.shiftKey || index < lastIndex && !e.shiftKey) {
e.preventDefault();
if (!$nextAppointment) {
e.shiftKey ? index-- : index++;
$nextAppointment = this.getFocusableItemBySortedIndex(index)
}
this.resetTabIndex($nextAppointment);
eventsEngine.trigger($nextAppointment, "focus")
}
}
delHandler(e) {
if (this._collection.option("allowDelete")) {
e.preventDefault();
const data = this._collection.getAppointmentSettings($(e.target)).itemData;
this._collection.notifyObserver("onDeleteButtonPress", {
data: data,
target: e.target
})
}
}
escHandler() {
if (!this._collection.isResizing) {
return
}
this._collection.moveAppointmentBack();
const resizableInstance = this.$focusedItem.dxResizable("instance");
if (resizableInstance) {
resizableInstance._detachEventHandlers();
resizableInstance._attachEventHandlers();
resizableInstance._toggleResizingClass(false)
}
}
}