devextreme
Version:
JavaScript/TypeScript Component Suite for Responsive Web Development
271 lines (270 loc) • 9.8 kB
JavaScript
/**
* DevExtreme (esm/__internal/scheduler/header/m_header.js)
* Version: 25.2.7
* Build date: Tue May 05 2026
*
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
import "../../../ui/drop_down_button";
import registerComponent from "../../../core/component_registrator";
import devices from "../../../core/devices";
import errors from "../../../core/errors";
import $ from "../../../core/renderer";
import {
getPathParts
} from "../../../core/utils/data";
import dateUtils from "../../../core/utils/date";
import {
extend
} from "../../../core/utils/extend";
import Toolbar from "../../../ui/toolbar";
import Widget from "../../core/widget/widget";
import SchedulerCalendar from "./m_calendar";
import {
getDateNavigator,
getTodayButtonOptions
} from "./m_date_navigator";
import {
getCaption,
getNextIntervalDate,
getStep,
nextWeek
} from "./m_utils";
import {
getDropDownViewSwitcher,
getTabViewSwitcher
} from "./m_view_switcher";
const CLASSES = {
component: "dx-scheduler-header",
invisible: "dx-state-invisible"
};
const ITEM_NAMES = {
today: "today",
dateNavigator: "dateNavigator",
viewSwitcher: "viewSwitcher"
};
export class SchedulerHeader extends Widget {
get captionText() {
return this.getCaption().text
}
getIntervalOptions(date) {
const {
currentView: currentView,
firstDayOfWeek: firstDayOfWeek
} = this.option();
const step = getStep(currentView.type);
return {
date: date,
step: step,
firstDayOfWeek: firstDayOfWeek,
intervalCount: currentView.intervalCount,
agendaDuration: currentView.agendaDuration
}
}
_getDefaultOptions() {
return extend(super._getDefaultOptions(), {
_useShortDateFormat: !devices.real().generic || devices.isSimulator()
})
}
createEventMap() {
this.eventMap = new Map([
["currentView", []],
["views", []],
["currentDate", [this.getCalendarOptionUpdater("value")]],
["min", [this.getCalendarOptionUpdater("min")]],
["max", [this.getCalendarOptionUpdater("max")]],
["tabIndex", [this.repaint.bind(this)]],
["focusStateEnabled", [this.repaint.bind(this)]],
["useDropDownViewSwitcher", [this.repaint.bind(this)]],
["indicatorTime", []]
])
}
addEvent(name, event) {
const events = this.eventMap.get(name) ?? [];
this.eventMap.set(name, [...events, event])
}
_optionChanged(args) {
const {
name: name,
value: value
} = args;
const events = this.eventMap.get(name);
null === events || void 0 === events || events.forEach(event => {
event(value)
})
}
onToolbarOptionChanged(fullName, value) {
var _this$toolbar, _this$toolbar2, _this$toolbar3;
const parts = getPathParts(fullName);
const optionName = fullName.replace(/^toolbar\./, "");
this.option(fullName, value);
this._toggleVisibility();
switch (true) {
case "toolbar" === fullName:
this.repaint();
break;
case "toolbar.items" === fullName:
null === (_this$toolbar = this.toolbar) || void 0 === _this$toolbar || _this$toolbar.option("items", value.map(item => this.parseItem(item)));
break;
case "items" === parts[1] && 3 === parts.length:
null === (_this$toolbar2 = this.toolbar) || void 0 === _this$toolbar2 || _this$toolbar2.option(optionName, this.parseItem(value));
break;
default:
null === (_this$toolbar3 = this.toolbar) || void 0 === _this$toolbar3 || _this$toolbar3.option(optionName, value)
}
}
_init() {
super._init();
this.createEventMap();
this.$element().addClass(CLASSES.component)
}
_render() {
super._render();
this.createEventMap();
this.renderToolbar();
this._toggleVisibility()
}
renderToolbar() {
const config = this.createToolbarConfig();
const toolbarElement = $("<div>");
toolbarElement.appendTo(this.$element());
this.toolbar = this._createComponent(toolbarElement, Toolbar, config)
}
_toggleVisibility() {
const {
toolbar: toolbar
} = this.option();
const isHeaderShown = toolbar.visible ?? toolbar.items.length;
if (isHeaderShown) {
this.$element().removeClass(CLASSES.invisible)
} else {
this.$element().addClass(CLASSES.invisible)
}
}
createToolbarConfig() {
const {
toolbar: toolbar
} = this.option();
const parsedItems = toolbar.items.map(element => this.parseItem(element));
return Object.assign({}, toolbar, {
items: parsedItems
})
}
parseItem(item) {
const itemName = "string" === typeof item ? item : item.name;
const itemOptions = "string" === typeof item ? {} : item;
if (itemName) {
switch (itemName) {
case ITEM_NAMES.today:
return getTodayButtonOptions(this, itemOptions);
case ITEM_NAMES.viewSwitcher:
return this.option().useDropDownViewSwitcher ? getDropDownViewSwitcher(this, itemOptions) : getTabViewSwitcher(this, itemOptions);
case ITEM_NAMES.dateNavigator:
this.renderCalendar();
return getDateNavigator(this, itemOptions);
default:
errors.log(`Unknown default element type: ${itemName}`)
}
}
return extend(true, {}, item)
}
callEvent(event, arg) {
const events = this.eventMap.get(event);
null === events || void 0 === events || events.forEach(EventMapHandler => EventMapHandler(arg))
}
updateCurrentView(view) {
const {
onCurrentViewChange: onCurrentViewChange
} = this.option();
onCurrentViewChange(view.name)
}
updateCalendarValueAndCurrentDate(date) {
var _this$calendar;
this.updateCurrentDate(date);
null === (_this$calendar = this.calendar) || void 0 === _this$calendar || _this$calendar.option("value", date)
}
updateCurrentDate(date) {
const {
onCurrentDateChange: onCurrentDateChange
} = this.option();
onCurrentDateChange(date);
this.callEvent("currentDate", date)
}
renderCalendar() {
const {
currentDate: currentDate,
min: min,
max: max,
firstDayOfWeek: firstDayOfWeek,
focusStateEnabled: focusStateEnabled,
tabIndex: tabIndex
} = this.option();
this.calendar = this._createComponent("<div>", SchedulerCalendar, {
value: currentDate,
min: min,
max: max,
firstDayOfWeek: firstDayOfWeek,
focusStateEnabled: focusStateEnabled,
tabIndex: tabIndex,
onValueChanged: async e => {
var _this$calendar2;
this.updateCurrentDate(e.value);
await (null === (_this$calendar2 = this.calendar) || void 0 === _this$calendar2 ? void 0 : _this$calendar2.hide())
}
});
this.calendar.$element().appendTo(this.$element())
}
getCalendarOptionUpdater(name) {
return value => {
if (this.calendar) {
this.calendar.option(name, value)
}
}
}
getNextDate(direction, initialDate) {
const {
currentDate: currentDate
} = this.option();
const date = initialDate ?? currentDate;
const options = this.getIntervalOptions(date);
return getNextIntervalDate(options, direction)
}
getDisplayedDate() {
const {
startViewDate: startViewDate,
currentView: currentView
} = this.option();
const isMonth = "month" === currentView.type;
return isMonth ? nextWeek(startViewDate) : startViewDate
}
getCaptionOptions() {
const {
currentDate: currentDate,
startViewDate: startViewDate
} = this.option();
let date = currentDate;
if (startViewDate) {
date = this.getDisplayedDate()
}
date = dateUtils.trimTime(date);
return this.getIntervalOptions(date)
}
getCaption() {
const {
customizeDateNavigatorText: customizeDateNavigatorText
} = this.option();
const options = this.getCaptionOptions();
const useShortDateFormat = this.option()._useShortDateFormat;
return getCaption(options, Boolean(useShortDateFormat), customizeDateNavigatorText)
}
updateDateByDirection(direction) {
const date = this.getNextDate(direction);
this.updateCalendarValueAndCurrentDate(date)
}
async showCalendar(e) {
var _this$calendar3;
await (null === (_this$calendar3 = this.calendar) || void 0 === _this$calendar3 ? void 0 : _this$calendar3.show(e.element))
}
}
registerComponent("dxSchedulerHeader", SchedulerHeader);