devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
339 lines (273 loc) • 12.8 kB
JavaScript
"use strict";
var $ = require("../../core/renderer"),
Class = require("../../core/class"),
translator = require("../../animation/translator"),
typeUtils = require("../../core/utils/type"),
dragEvents = require("../../events/drag"),
eventUtils = require("../../events/utils"),
eventsEngine = require("../../events/core/events_engine"),
Button = require("../button"),
DropDownMenu = require("../drop_down_menu"),
FunctionTemplate = require("../widget/function_template"),
messageLocalization = require("../../localization/message"),
extendFromObject = require("../../core/utils/extend").extendFromObject,
deferredUtils = require("../../core/utils/deferred"),
when = deferredUtils.when;
var DROPDOWN_APPOINTMENTS_CLASS = "dx-scheduler-dropdown-appointments",
DROPDOWN_APPOINTMENTS_CONTENT_CLASS = "dx-scheduler-dropdown-appointments-content",
DROPDOWN_APPOINTMENT_CLASS = "dx-scheduler-dropdown-appointment",
DROPDOWN_APPOINTMENT_TITLE_CLASS = "dx-scheduler-dropdown-appointment-title",
DROPDOWN_APPOINTMENT_DATE_CLASS = "dx-scheduler-dropdown-appointment-date",
DROPDOWN_APPOINTMENT_REMOVE_BUTTON_CLASS = "dx-scheduler-dropdown-appointment-remove-button",
DROPDOWN_APPOINTMENT_INFO_BLOCK_CLASS = "dx-scheduler-dropdown-appointment-info-block",
DROPDOWN_APPOINTMENT_BUTTONS_BLOCK_CLASS = "dx-scheduler-dropdown-appointment-buttons-block";
var DRAG_START_EVENT_NAME = eventUtils.addNamespace(dragEvents.start, "dropDownAppointments"),
DRAG_UPDATE_EVENT_NAME = eventUtils.addNamespace(dragEvents.move, "dropDownAppointments"),
DRAG_END_EVENT_NAME = eventUtils.addNamespace(dragEvents.end, "dropDownAppointments");
var SIDE_BORDER_COLOR_STYLES = {
"left": "borderLeftColor",
"top": "borderTopColor",
"right": "borderRightColor",
"bottom": "borderBottomColor"
};
var dropDownAppointments = Class.inherit({
render: function render(options, instance) {
var coordinates = options.coordinates,
items = options.items;
this.instance = instance;
var $menu = $("<div>").addClass(DROPDOWN_APPOINTMENTS_CLASS).appendTo(options.$container);
this._createAppointmentClickAction();
this._createDropDownMenu({
$element: $menu,
items: items,
itemTemplate: options.itemTemplate,
buttonWidth: options.buttonWidth
});
var deferredButtonColor = options.buttonColor,
deferredItemsColors = options.items.colors;
when.apply(null, deferredItemsColors).done(function () {
this._paintMenuButton($menu, deferredButtonColor, arguments);
}.bind(this));
this._applyInnerShadow($menu, options.buttonWidth);
translator.move($menu, {
top: coordinates.top,
left: coordinates.left
});
return $menu;
},
repaintExisting: function repaintExisting($container) {
var appointmentsSelector = ["", DROPDOWN_APPOINTMENTS_CLASS, "dx-dropdownmenu"].join(".");
$container.find(appointmentsSelector).each(function () {
DropDownMenu.getInstance(this).repaint();
});
},
_paintMenuButton: function _paintMenuButton($menu, color, itemsColors) {
var paintButton = true,
itemColorCount = itemsColors.length,
currentItemColor;
color && color.done(function (color) {
if (itemColorCount) {
currentItemColor = itemsColors[0];
for (var i = 1; i < itemColorCount; i++) {
if (currentItemColor !== itemsColors[i]) {
paintButton = false;
break;
}
currentItemColor = color;
}
}
if (color && paintButton) {
$menu.css("backgroundColor", color);
}
}.bind(this));
},
_createButtonTemplate: function _createButtonTemplate(appointmentCount) {
return $("<div>").append([$("<span>").text(messageLocalization.getFormatter("dxScheduler-moreAppointments")(appointmentCount))]).addClass(DROPDOWN_APPOINTMENTS_CONTENT_CLASS);
},
_applyInnerShadow: function _applyInnerShadow($element) {
$element.css("boxShadow", "inset " + $element.get(0).getBoundingClientRect().width + "px 0 0 0 rgba(0, 0, 0, 0.3)");
},
_createAppointmentClickAction: function _createAppointmentClickAction() {
this._appointmentClickAction = this.instance._createActionByOption("onAppointmentClick", {
afterExecute: function (e) {
var config = e.args[0];
config.event.stopPropagation();
this.instance.fire("showEditAppointmentPopup", { data: config.appointmentData });
}.bind(this)
});
},
_createDropDownMenu: function _createDropDownMenu(config) {
var $menu = config.$element,
items = config.items,
that = this;
if (!DropDownMenu.getInstance($menu)) {
this._initDynamicTemplate(items);
var template = this.instance._getAppointmentTemplate("dropDownAppointmentTemplate");
this.instance._createComponent($menu, DropDownMenu, {
buttonIcon: null,
usePopover: true,
popupHeight: "auto",
popupMaxHeight: 200,
items: items.data,
buttonTemplate: this._createButtonTemplate(items.data.length),
buttonWidth: config.buttonWidth,
closeOnClick: false,
onItemClick: function onItemClick(args) {
var mappedData = that.instance.fire("mapAppointmentFields", args);
that._appointmentClickAction(extendFromObject(mappedData, args, false));
},
activeStateEnabled: false,
focusStateEnabled: this.instance.option("focusStateEnabled"),
itemTemplate: new FunctionTemplate(function (options) {
return template.render({
model: options.model,
index: options.index,
container: options.container
});
}),
onItemRendered: function onItemRendered(args) {
if (!that.instance._allowDragging()) {
return;
}
var $item = args.itemElement,
itemData = args.itemData,
settings = itemData.settings;
eventsEngine.on($item, DRAG_START_EVENT_NAME, that._dragStartHandler.bind(that, $item, itemData, settings, $menu));
eventsEngine.on($item, DRAG_UPDATE_EVENT_NAME, function (e) {
DropDownMenu.getInstance($menu).close();
that._dragHandler(e, itemData.allDay);
}.bind(this));
eventsEngine.on($item, DRAG_END_EVENT_NAME, function (e) {
eventsEngine.trigger(that._$draggedItem, "dxdragend");
delete that._$draggedItem;
}.bind(this));
}
});
}
},
_dragStartHandler: function _dragStartHandler($item, itemData, settings, $menu, e) {
var appointmentInstance = this.instance.getAppointmentsInstance(),
appointmentIndex = appointmentInstance.option("items").length;
settings[0].isCompact = false;
settings[0].virtual = false;
var appointmentData = {
itemData: itemData,
settings: settings
};
appointmentInstance._currentAppointmentSettings = settings;
appointmentInstance._renderItem(appointmentIndex, appointmentData);
var $items = appointmentInstance._findItemElementByItem(itemData);
if (!$items.length) {
return;
}
this._$draggedItem = $items.length > 1 ? this._getRecurrencePart($items, appointmentData.settings[0].startDate) : $items[0];
var menuPosition = translator.locate($menu),
itemPosition = translator.locate(this._$draggedItem);
this._startPosition = {
top: itemPosition.top,
left: menuPosition.left
};
translator.move(this._$draggedItem, this._startPosition);
eventsEngine.trigger(this._$draggedItem, "dxdragstart");
},
_dragHandler: function _dragHandler(e, allDay) {
var coordinates = {
left: this._startPosition.left + e.offset.x,
top: this._startPosition.top + e.offset.y
};
this.instance.getAppointmentsInstance().notifyObserver("correctAppointmentCoordinates", {
coordinates: coordinates,
allDay: allDay,
isFixedContainer: false,
callback: function callback(result) {
if (result) {
coordinates = result;
}
}
});
translator.move(this._$draggedItem, coordinates);
},
_getRecurrencePart: function _getRecurrencePart(appointments, startDate) {
var result;
for (var i = 0; i < appointments.length; i++) {
var $appointment = appointments[i],
appointmentStartDate = $appointment.data("dxAppointmentStartDate");
if (appointmentStartDate.getTime() === startDate.getTime()) {
result = $appointment;
}
}
return result;
},
_initDynamicTemplate: function _initDynamicTemplate(items) {
var that = this;
this.instance._defaultTemplates["dropDownAppointment"] = new FunctionTemplate(function (options) {
return that._createDropDownAppointmentTemplate(options.model, $(options.container), items.colors[options.index]);
});
},
_createDropDownAppointmentTemplate: function _createDropDownAppointmentTemplate(appointmentData, appointmentElement, color) {
var dateString = "",
appointmentMarkup = [],
borderSide = "left",
$title,
$date,
$infoBlock,
text = this.instance.fire("getField", "text", appointmentData);
appointmentElement.addClass(DROPDOWN_APPOINTMENT_CLASS);
if (this.instance.option("rtlEnabled")) {
borderSide = "right";
}
color && color.done(function (color) {
appointmentElement.css(SIDE_BORDER_COLOR_STYLES[borderSide], color);
}.bind(this));
var startDate = this.instance.fire("getField", "startDate", appointmentData),
endDate = this.instance.fire("getField", "endDate", appointmentData);
this.instance.fire("formatDates", {
startDate: startDate,
endDate: endDate,
formatType: "DATETIME",
callback: function callback(result) {
dateString = result;
}
});
$infoBlock = $("<div>").addClass(DROPDOWN_APPOINTMENT_INFO_BLOCK_CLASS);
$title = $("<div>").addClass(DROPDOWN_APPOINTMENT_TITLE_CLASS).text(text);
$date = $("<div>").addClass(DROPDOWN_APPOINTMENT_DATE_CLASS).text(dateString);
$infoBlock.append([$title, $date]);
appointmentMarkup.push($infoBlock);
appointmentMarkup.push(this._createButtons(appointmentData));
appointmentElement.append(appointmentMarkup);
return appointmentElement;
},
_createButtons: function _createButtons(appointmentData) {
var editing = this.instance.option("editing"),
allowDeleting = false,
allowUpdating = false;
if (!editing) {
return "";
}
if (editing === true) {
allowDeleting = true;
allowUpdating = true;
}
if (typeUtils.isObject(editing)) {
allowDeleting = editing.allowDeleting;
allowUpdating = editing.allowUpdating;
}
var $container = $("<div>").addClass(DROPDOWN_APPOINTMENT_BUTTONS_BLOCK_CLASS),
$removeButton = $("<div>").addClass(DROPDOWN_APPOINTMENT_REMOVE_BUTTON_CLASS);
if (allowDeleting) {
$container.append($removeButton);
this.instance._createComponent($removeButton, Button, {
icon: "trash",
height: 25,
width: 25,
onClick: function (e) {
e.event.stopPropagation();
this.instance.deleteAppointment(appointmentData);
}.bind(this)
});
}
return $container;
}
});
module.exports = dropDownAppointments;