@openui5/sap.m
Version:
OpenUI5 UI Library sap.m
1,316 lines (1,133 loc) • 90.7 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2009-2023 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
// Provides control sap.m.SinglePlanningCalendarGrid.
sap.ui.define([
'./SinglePlanningCalendarUtilities',
'./library',
'sap/ui/unified/DateRange',
'sap/ui/core/Control',
'sap/ui/core/LocaleData',
'sap/ui/core/Locale',
'sap/ui/core/InvisibleText',
'sap/ui/core/format/DateFormat',
'sap/ui/core/format/TimezoneUtil',
'sap/ui/core/Core',
'sap/ui/core/date/UniversalDate',
'sap/ui/core/dnd/DragDropInfo',
'sap/ui/unified/library',
'sap/ui/unified/calendar/DatesRow',
'sap/ui/unified/calendar/CalendarDate',
'sap/ui/unified/calendar/CalendarUtils',
'sap/ui/unified/DateTypeRange',
'sap/ui/events/KeyCodes',
'./SinglePlanningCalendarGridRenderer',
'sap/ui/core/delegate/ItemNavigation',
"sap/ui/thirdparty/jquery",
'./PlanningCalendarLegend',
'sap/ui/core/InvisibleMessage',
'sap/ui/core/library',
"sap/ui/core/date/CalendarUtils",
"sap/ui/core/Configuration",
"sap/ui/core/date/UI5Date"
],
function (
SinglePlanningCalendarUtilities,
library,
DateRange,
Control,
LocaleData,
Locale,
InvisibleText,
DateFormat,
TimezoneUtil,
Core,
UniversalDate,
DragDropInfo,
unifiedLibrary,
DatesRow,
CalendarDate,
CalendarUtils,
DateTypeRange,
KeyCodes,
SinglePlanningCalendarGridRenderer,
ItemNavigation,
jQuery,
PlanningCalendarLegend,
InvisibleMessage,
coreLibrary,
CalendarDateUtils,
Configuration,
UI5Date
) {
"use strict";
var ROW_HEIGHT_COZY = 4.3125, // Unit in rem, equals 69px with default font size
ROW_HEIGHT_COMPACT = 3, // Unit in rem, equals 48px with default font size
BLOCKER_ROW_HEIGHT_COZY = 2.125, // Unit in rem, equals 34px with default font size
BLOCKER_ROW_HEIGHT_COMPACT = 1.5625, // Unit in rem, equals 25px with default font size
HALF_HOUR_MS = 3600000 / 2,
ONE_MIN_MS = 60 * 1000,
// Day view only - indicates the special dates
// 3px height the marker itself + 2x2px on its top and bottom both on cozy & compact
DAY_MARKER_HEIGHT = 0.4375, // Unit in rem, equals 7px with default font size
FIRST_HOUR_OF_DAY = 0,
LAST_HOUR_OF_DAY = 24,
InvisibleMessageMode = coreLibrary.InvisibleMessageMode,
CalendarType = coreLibrary.CalendarType,
SinglePlanningCalendarSelectionMode = library.SinglePlanningCalendarSelectionMode;
/**
* Constructor for a new SinglePlanningCalendarGrid.
*
* @param {string} [sId] id for the new control, generated automatically if no id is given
* @param {object} [mSettings] initial settings for the new control
*
* @class
*
* Displays a grid in which appointments of the {@link sap.m.SinglePlanningCalendar} are rendered.
*
* <h3>Overview</h3>
*
* <b>Note:</b> The <code>PlanningCalendarGrid</code> uses parts of the <code>sap.ui.unified</code> library.
* This library will be loaded after the <code>PlanningCalendarGrid</code>, if it wasn't previously loaded.
* This could lead to a waiting time when a <code>PlanningCalendarGrid</code> is used for the first time.
* To prevent this, apps using the <code>PlanningCalendarGrid</code> must also load the
* <code>sap.ui.unified</code> library.
*
* The <code>PlanningCalendarGrid</code> has the following structure:
*
* <ul>
* <li>Each column in the grid represents a single entity of the view type. For example in the week view one
* column represents a week day.</li>
* <li>Each row represents an hour from each day.</li>
* <li>There are also appointments displayed across the grid. To display an all-day appointment, the
* appointment must start at 00:00 and end on any day in the future in 00:00h.</li>
* </ul>
*
* @extends sap.ui.core.Control
*
* @author SAP SE
* @version 1.117.4
*
* @constructor
* @private
* @since 1.61
* @alias sap.m.SinglePlanningCalendarGrid
*/
var SinglePlanningCalendarGrid = Control.extend("sap.m.SinglePlanningCalendarGrid", /** @lends sap.m.SinglePlanningCalendarGrid.prototype */ {
metadata: {
library: "sap.m",
properties: {
/**
* Determines the start date of the grid, as a UI5Date or JavaScript Date object. It is considered as a local date.
* The time part will be ignored. The current date is used as default.
*/
startDate: {type: "object", group: "Data"},
/**
* Determines the start hour of the grid to be shown if the <code>fullDay</code> property is set to
* <code>false</code>. Otherwise the previous hours are displayed as non-working. The passed hour is
* considered as 24-hour based.
*/
startHour: {type: "int", group: "Data", defaultValue: 0},
/**
* Determines the end hour of the grid to be shown if the <code>fullDay</code> property is set to
* <code>false</code>. Otherwise the next hours are displayed as non-working. The passed hour is
* considered as 24-hour based.
*/
endHour: {type: "int", group: "Data", defaultValue: 24},
/**
* Determines if all of the hours in a day are displayed. If set to <code>false</code>, the hours shown are
* between the <code>startHour</code> and <code>endHour</code>.
*/
fullDay: {type: "boolean", group: "Data", defaultValue: true},
/**
* Determines whether the appointments in the grid are draggable.
*
* The drag and drop interaction is visualized by a placeholder highlighting the area where the
* appointment can be dropped by the user.
*
* @since 1.64
*/
enableAppointmentsDragAndDrop: { type: "boolean", group: "Misc", defaultValue: false },
/**
* Determines whether the appointments are resizable.
*
* The resize interaction is visualized by making the appointment transparent.
*
* The appointment snaps on every interval
* of 30 minutes. After the resize is finished, the {@link #event:appointmentResize appointmentResize} event is fired, containing
* the new start and end UI5Date or JavaScript Date objects.
*
* @since 1.65
*/
enableAppointmentsResize: { type: "boolean", group: "Misc", defaultValue: false },
/**
* Determines whether the appointments can be created by dragging on empty cells.
*
* See {@link #property:enableAppointmentsResize enableAppointmentsResize} for the specific points for events snapping
*
* @since 1.65
*/
enableAppointmentsCreate: { type: "boolean", group: "Misc", defaultValue: false },
/**
* Determines scale factor for the appointments.
*
* Acceptable range is from 1 to 6.
* @since 1.99
*/
scaleFactor: {type: "float", group: "Data", defaultValue: 1},
/**
* If set, the calendar week numbering is used for display.
* If not set, the calendar week numbering of the global configuration is used.
* @since 1.110.0
*/
calendarWeekNumbering : { type : "sap.ui.core.date.CalendarWeekNumbering", group : "Appearance", defaultValue: null},
/* Determines whether more than one day will be selectable.
* <b>Note:</b> selecting more than one day is possible with a combination of <code>Ctrl + mouse click</code>
*/
dateSelectionMode: { type: "sap.m.SinglePlanningCalendarSelectionMode", group: "Behavior", defaultValue: SinglePlanningCalendarSelectionMode.SingleSelect }
},
aggregations: {
/**
* The appointments to be displayed in the grid. Appointments outside the visible time frame are not rendered.
* Appointments, longer than a day, will be displayed in all of the affected days.
* An appointment which starts at 00:00 and ends in 00:00 on any day in the future is displayed as an all-day
* appointment.
*/
appointments: {type: "sap.ui.unified.CalendarAppointment", multiple: true, singularName: "appointment", dnd : {draggable: true}},
/**
* Special days in the header visualized as a date range with type.
*
* <b>Note:</b> If one day is assigned to more than one type, only the first type is used.
* @since 1.66
*/
specialDates : {type : "sap.ui.unified.DateTypeRange", multiple : true, singularName : "specialDate"},
/**
* Hidden, for internal use only.
* The date row which shows the header of the columns in the <code>SinglePlanningCalendarGrid</code>.
*
* @private
*/
_columnHeaders: {type: "sap.ui.unified.calendar.DatesRow", multiple: false, visibility: "hidden"},
_intervalPlaceholders : {type : "sap.m.SinglePlanningCalendarGrid._internal.IntervalPlaceholder", multiple : true, visibility : "hidden", dnd : {droppable: true}},
_blockersPlaceholders : {type : "sap.m.SinglePlanningCalendarGrid._internal.IntervalPlaceholder", multiple : true, visibility : "hidden", dnd : {droppable: true}},
/**
* Dates or date ranges for selected dates.
*
* To set a single date (instead of a range), set only the <code>startDate</code> property
* of the {@link sap.ui.unified.DateRange} class.
*/
selectedDates : {type : "sap.ui.unified.DateRange", multiple : true, singularName : "selectedDate"}
},
dnd: true,
associations: {
/**
* Association to controls / IDs which label this control (see WAI-ARIA attribute aria-labelledby).
*
* <b>Note</b> These labels are also assigned to the appointments.
*/
ariaLabelledBy: {type: "sap.ui.core.Control", multiple: true, singularName: "ariaLabelledBy"},
/**
* Association to the <code>PlanningCalendarLegend</code> explaining the colors of the <code>Appointments</code>.
*
* <b>Note:</b> The legend does not have to be rendered but must exist and all required types must be assigned.
* @since 1.66.0
*/
legend: { type: "sap.m.PlanningCalendarLegend", multiple: false}
},
events: {
/**
* Fired when the selected state of an appointment is changed.
*/
appointmentSelect: {
parameters: {
/**
* The appointment on which the event was triggered.
*/
appointment: {type: "sap.ui.unified.CalendarAppointment"},
/**
* All appointments with changed selected state.
* @since 1.67.0
*/
appointments : {type : "sap.ui.unified.CalendarAppointment[]"}
}
},
/**
* Fired if an appointment is dropped.
* @since 1.64
*/
appointmentDrop : {
parameters : {
/**
* The dropped appointment.
*/
appointment : {type : "sap.ui.unified.CalendarAppointment"},
/**
* Start date of the dropped appointment, as a UI5Date or JavaScript Date object.
*/
startDate : {type : "object"},
/**
* Dropped appointment end date as a UI5Date or JavaScript Date object.
*/
endDate : {type : "object"},
/**
* The drop type. If true - it's "Copy", if false - it's "Move".
*/
copy : {type : "boolean"}
}
},
/**
* Fired if an appointment is resized.
* @since 1.65
*/
appointmentResize: {
parameters: {
/**
* The resized appointment.
*/
appointment: { type: "sap.ui.unified.CalendarAppointment" },
/**
* Start date of the dropped appointment, as a UI5Date or JavaScript Date object.
*/
startDate: { type: "object" },
/**
* Dropped appointment end date as a UI5Date or JavaScript Date object.
*/
endDate: { type: "object" }
}
},
/**
* Fired if an appointment is created.
* @since 1.65
*/
appointmentCreate: {
parameters: {
/**
* Start date of the created appointment, as a UI5Date or JavaScript Date object.
*/
startDate: {type: "object"},
/**
* End date of the created appointment, as a UI5Date or JavaScript Date object.
*/
endDate: {type: "object"}
}
},
/**
* Fired when a grid cell is pressed.
* @since 1.65
*/
cellPress: {
parameters: {
/**
* The start date as a UI5Date or JavaScript Date object of the focused grid cell.
*/
startDate: {type: "object"},
/**
* The end date as a UI5Date or JavaScript Date object of the focused grid cell.
*/
endDate: {type: "object"}
}
}
}
},
renderer: SinglePlanningCalendarGridRenderer
});
SinglePlanningCalendarGrid.prototype.init = function () {
var oStartDate = UI5Date.getInstance(),
oDatesRow = new DatesRow(this.getId() + "-columnHeaders", {
showDayNamesLine: false,
showWeekNumbers: false,
singleSelection: false,
startDate: oStartDate,
calendarWeekNumbering: this.getCalendarWeekNumbering()
}).addStyleClass("sapMSinglePCColumnHeader"),
iDelay = (60 - oStartDate.getSeconds()) * 1000,
sTimePattern = this._getCoreLocaleData().getTimePattern("medium");
oDatesRow._setAriaRole("columnheader");
this.setAggregation("_columnHeaders", oDatesRow);
this.setStartDate(oStartDate);
this._setColumns(7);
this._configureBlockersDragAndDrop();
this._configureAppointmentsDragAndDrop();
this._configureAppointmentsResize();
this._configureAppointmentsCreate();
this._oUnifiedRB = sap.ui.getCore().getLibraryResourceBundle("sap.ui.unified");
this._oFormatStartEndInfoAria = DateFormat.getDateTimeInstance({
pattern: "EEEE dd/MM/yyyy 'at' " + sTimePattern
});
this._oFormatAriaFullDayCell = DateFormat.getDateTimeInstance({
pattern: "EEEE dd/MM/yyyy"
});
this._oFormatYyyymmdd = DateFormat.getInstance({pattern: "yyyyMMdd", calendarType: CalendarType.Gregorian});
//the id of the SPC's legend if any
this._sLegendId = undefined;
setTimeout(this._updateRowHeaderAndNowMarker.bind(this), iDelay);
};
SinglePlanningCalendarGrid.prototype.exit = function () {
if (this._oItemNavigation) {
this.removeDelegate(this._oItemNavigation);
this._oItemNavigation.destroy();
delete this._oItemNavigation;
}
};
SinglePlanningCalendarGrid.prototype.onBeforeRendering = function () {
var oAppointmentsMap = this._createAppointmentsMap(this.getAppointments()),
oStartDate = this.getStartDate(),
oCalStartDate = CalendarDate.fromLocalJSDate(oStartDate),
iColumns = this._getColumns();
this._oVisibleAppointments = this._calculateVisibleAppointments(oAppointmentsMap.appointments, this.getStartDate(), iColumns);
this._oAppointmentsToRender = this._calculateAppointmentsLevelsAndWidth(this._oVisibleAppointments);
this._aVisibleBlockers = this._calculateVisibleBlockers(oAppointmentsMap.blockers, oCalStartDate, iColumns);
this._oBlockersToRender = this._calculateBlockersLevelsAndWidth(this._aVisibleBlockers);
if (this._iOldColumns !== iColumns || this._oOldStartDate !== oStartDate) {
this._createBlockersDndPlaceholders(oStartDate, iColumns);
this._createAppointmentsDndPlaceholders(oStartDate, iColumns);
}
this._oInvisibleMessage = InvisibleMessage.getInstance();
};
SinglePlanningCalendarGrid.prototype.setCalendarWeekNumbering = function (sCalendarWeekNumbering){
this.setProperty("calendarWeekNumbering",sCalendarWeekNumbering);
var oDatesRow = this.getAggregation("_columnHeaders");
oDatesRow.setCalendarWeekNumbering(sCalendarWeekNumbering);
return this;
};
SinglePlanningCalendarGrid.prototype.onmousedown = function(oEvent) {
var oClassList = oEvent.target.classList;
this._isResizeHandleBottomMouseDownTarget = oClassList.contains("sapMSinglePCAppResizeHandleBottom");
this._isResizeHandleTopMouseDownTarget = oClassList.contains("sapMSinglePCAppResizeHandleTop");
};
SinglePlanningCalendarGrid.prototype._isResizingPerformed = function() {
return this._isResizeHandleBottomMouseDownTarget || this._isResizeHandleTopMouseDownTarget;
};
SinglePlanningCalendarGrid.prototype._configureBlockersDragAndDrop = function () {
this.addDragDropConfig(new DragDropInfo({
sourceAggregation: "appointments",
targetAggregation: "_blockersPlaceholders",
dragStart: function (oEvent) {
if (!this.getEnableAppointmentsDragAndDrop()) {
oEvent.preventDefault();
return false;
}
var fnHandleAppsOverlay = function () {
var $Overlay = jQuery(".sapMSinglePCOverlay");
setTimeout(function () {
$Overlay.addClass("sapMSinglePCOverlayDragging");
});
jQuery(document).one("dragend", function () {
$Overlay.removeClass("sapMSinglePCOverlayDragging");
});
};
fnHandleAppsOverlay();
}.bind(this),
dragEnter: function (oEvent) {
var oDragSession = oEvent.getParameter("dragSession"),
oAppointment = oDragSession.getDragControl(),
oDropTarget = oDragSession.getDropControl(),
bIsFullDay = this.isAllDayAppointment(oAppointment.getStartDate(), oAppointment.getEndDate()),
fnAlignIndicator = function () {
var $Indicator = jQuery(oDragSession.getIndicator()),
iAppHeight = oAppointment.$().outerHeight(),
iAppWidth = oAppointment.$().outerWidth(),
oGrid = oDropTarget.$().closest(".sapMSinglePCBlockersColumns").get(0).getBoundingClientRect(),
oDropDim = oDropTarget.getDomRef().getBoundingClientRect(),
iSubtractFromWidth = (oDropDim.left + iAppWidth) - (oGrid.left + oGrid.width);
if (bIsFullDay) {
$Indicator.css("min-height", iAppHeight);
$Indicator.css("min-width", Math.min(iAppWidth, iAppWidth - iSubtractFromWidth));
} else {
$Indicator.css("min-height", oDragSession.getDropControl().$().outerHeight());
$Indicator.css("min-width", oDragSession.getDropControl().$().outerWidth());
}
};
if (!oDragSession.getIndicator()) {
setTimeout(fnAlignIndicator, 0);
} else {
fnAlignIndicator();
}
}.bind(this),
drop: function (oEvent) {
var oDragSession = oEvent.getParameter("dragSession"),
oAppointment = oDragSession.getDragControl(),
oPlaceholder = oDragSession.getDropControl(),
oStartDate = oPlaceholder.getDate().getJSDate(),
oEndDate,
oBrowserEvent = oEvent.getParameter("browserEvent"),
bCopy = (oBrowserEvent.metaKey || oBrowserEvent.ctrlKey),
bIsFullDay = this.isAllDayAppointment(oAppointment.getStartDate(), oAppointment.getEndDate());
oEndDate = UI5Date.getInstance(oStartDate);
if (bIsFullDay) {
oEndDate.setMilliseconds(oAppointment.getEndDate().getTime() - oAppointment.getStartDate().getTime());
}
this.$().find(".sapMSinglePCOverlay").removeClass("sapMSinglePCOverlayDragging");
if (bIsFullDay && oAppointment.getStartDate().getTime() === oStartDate.getTime()) {
return;
}
this.fireAppointmentDrop({
appointment: oAppointment,
startDate: oStartDate,
endDate: oEndDate,
copy: bCopy
});
}.bind(this)
}));
};
SinglePlanningCalendarGrid.prototype._configureAppointmentsDragAndDrop = function () {
this.addDragDropConfig(new DragDropInfo({
sourceAggregation: "appointments",
targetAggregation: "_intervalPlaceholders",
dragStart: function (oEvent) {
if (!this.getEnableAppointmentsDragAndDrop() || this._isResizingPerformed()) {
oEvent.preventDefault();
return false;
}
var fnHandleAppsOverlay = function () {
var $Overlay = jQuery(".sapMSinglePCOverlay");
setTimeout(function () {
$Overlay.addClass("sapMSinglePCOverlayDragging");
});
jQuery(document).one("dragend", function () {
$Overlay.removeClass("sapMSinglePCOverlayDragging");
});
};
fnHandleAppsOverlay();
}.bind(this),
dragEnter: function (oEvent) {
var oDragSession = oEvent.getParameter("dragSession"),
oAppointment = oDragSession.getDragControl(),
oDropTarget = oDragSession.getDropControl(),
bIsFullDay = this.isAllDayAppointment(oAppointment.getStartDate(), oAppointment.getEndDate()),
fnAlignIndicator = function () {
var $Indicator = jQuery(oDragSession.getIndicator()),
iAppHeight = oAppointment.$().outerHeight(),
oGrid = oDropTarget.$().closest(".sapMSinglePCColumn").get(0).getBoundingClientRect(),
oDropDim = oDragSession.getDropControl().getDomRef().getBoundingClientRect(),
iSubtractFromHeight = (oDropDim.top + iAppHeight) - (oGrid.top + oGrid.height);
if (bIsFullDay) {
$Indicator.css("min-height", 2 * oDragSession.getDropControl().$().outerHeight());
} else {
$Indicator.css("min-height", Math.min(iAppHeight, iAppHeight - iSubtractFromHeight));
}
};
if (!oDragSession.getIndicator()) {
setTimeout(fnAlignIndicator, 0);
} else {
fnAlignIndicator();
}
}.bind(this),
drop: function (oEvent) {
var oDragSession = oEvent.getParameter("dragSession"),
oAppointment = oDragSession.getDragControl(),
oPlaceholder = oDragSession.getDropControl(),
oStartDate = oPlaceholder.getDate().getJSDate(),
oEndDate,
oBrowserEvent = oEvent.getParameter("browserEvent"),
bCopy = (oBrowserEvent.metaKey || oBrowserEvent.ctrlKey),
bIsFullDay = this.isAllDayAppointment(oAppointment.getStartDate(), oAppointment.getEndDate());
oEndDate = UI5Date.getInstance(oStartDate);
if (bIsFullDay) {
oEndDate.setHours(oEndDate.getHours() + 1);
} else {
oEndDate.setMilliseconds(oAppointment.getEndDate().getTime() - oAppointment.getStartDate().getTime());
}
this.$().find(".sapMSinglePCOverlay").removeClass("sapMSinglePCOverlayDragging");
if (!bIsFullDay && oAppointment.getStartDate().getTime() === oStartDate.getTime()) {
return;
}
this.fireAppointmentDrop({
appointment: oAppointment,
startDate: oStartDate,
endDate: oEndDate,
copy: bCopy
});
}.bind(this)
}));
};
SinglePlanningCalendarGrid.prototype._configureAppointmentsResize = function() {
var oResizeConfig = new DragDropInfo({
sourceAggregation: "appointments",
targetAggregation: "_intervalPlaceholders",
/**
* Fired when the user starts dragging an appointment.
*/
dragStart: function(oEvent) {
if (!this.getEnableAppointmentsResize() || !this._isResizingPerformed()) {
oEvent.preventDefault();
return;
}
var oDragSession = oEvent.getParameter("dragSession"),
oDragControl = oDragSession.getDragControl(),
oEventTarget = oEvent.getParameter("browserEvent") && oEvent.getParameter("browserEvent").target || null;
oDragControl._sAppointmentPartSuffix = oEventTarget && oEventTarget.id ? oEventTarget.id.replace(oDragControl.getId() + "-", "") : "";
var $SPCGridOverlay = this.$().find(".sapMSinglePCOverlay"),
$Indicator = jQuery(oDragSession.getIndicator()),
$DraggedControl = oDragControl.$();
if (this._isResizeHandleBottomMouseDownTarget) {
oDragSession.setComplexData("bottomHandle", "true");
}
if (this._isResizeHandleTopMouseDownTarget) {
oDragSession.setComplexData("topHandle", "true");
}
$Indicator.addClass("sapUiDnDIndicatorHide");
setTimeout(function() {
$SPCGridOverlay.addClass("sapMSinglePCOverlayDragging");
}, 0);
jQuery(document).one("dragend", function() {
var oAppointmentStartingBoundaries = oDragSession.getComplexData("appointmentStartingBoundaries");
$SPCGridOverlay.removeClass("sapMSinglePCOverlayDragging");
$Indicator.removeClass("sapUiDnDIndicatorHide");
$DraggedControl.css({
top: oAppointmentStartingBoundaries.top,
height: oAppointmentStartingBoundaries.height,
"z-index": "auto",
opacity: 1
});
});
oEvent.getParameter("browserEvent").dataTransfer.setDragImage(getResizeGhost(), 0, 0);
}.bind(this),
/**
* Fired when a dragged appointment enters a drop target.
*/
dragEnter: function(oEvent) {
var oDragSession = oEvent.getParameter("dragSession"),
oAppointmentRef = oDragSession.getDragControl().$().get(0),
oDropTarget = oDragSession.getDropControl().getDomRef(),
oAppointmentStartingBoundaries = oDragSession.getComplexData("appointmentStartingBoundaries"),
fnHideIndicator = function() {
var $Indicator = jQuery(oDragSession.getIndicator());
$Indicator.addClass("sapUiDnDIndicatorHide");
},
iTop,
iBottom,
iHeight,
iVariableBoundaryY,
mDraggedControlConfig;
if (!oAppointmentStartingBoundaries) {
oAppointmentStartingBoundaries = {
top: oAppointmentRef.offsetTop,
bottom: oAppointmentRef.offsetTop + oAppointmentRef.getBoundingClientRect().height,
height: oAppointmentRef.getBoundingClientRect().height
};
oDragSession.setComplexData("appointmentStartingBoundaries", oAppointmentStartingBoundaries);
}
iVariableBoundaryY = oDragSession.getData("bottomHandle") ? oAppointmentStartingBoundaries.top : oAppointmentStartingBoundaries.bottom;
iTop = Math.min(iVariableBoundaryY, oDropTarget.offsetTop);
iBottom = Math.max(iVariableBoundaryY, oDropTarget.offsetTop + oDropTarget.getBoundingClientRect().height);
iHeight = iBottom - iTop;
mDraggedControlConfig = {
top: iTop,
height: iHeight,
"z-index": 1,
opacity: 0.8
};
oDragSession.getDragControl().$().css(mDraggedControlConfig);
if (!oDragSession.getIndicator()) {
setTimeout(fnHideIndicator, 0);
} else {
fnHideIndicator();
}
},
/**
* Fired when an appointment is dropped.
*/
drop: function(oEvent) {
var oDragSession = oEvent.getParameter("dragSession"),
oAppointment = oDragSession.getDragControl(),
iIndex = this.indexOfAggregation("_intervalPlaceholders", oDragSession.getDropControl()),
oAppointmentStartingBoundaries = oDragSession.getComplexData("appointmentStartingBoundaries"),
newPos;
newPos = this._calcResizeNewHoursAppPos(
oAppointment.getStartDate(),
oAppointment.getEndDate(),
iIndex,
oDragSession.getComplexData("bottomHandle")
);
this.$().find(".sapMSinglePCOverlay").removeClass("sapMSinglePCOverlayDragging");
jQuery(oDragSession.getIndicator()).removeClass("sapUiDnDIndicatorHide");
oAppointment.$().css({
top: oAppointmentStartingBoundaries.top,
height: oAppointmentStartingBoundaries.height,
"z-index": "auto",
opacity: 1
});
if (oAppointment.getEndDate().getTime() === newPos.endDate.getTime() &&
oAppointment.getStartDate().getTime() === newPos.startDate.getTime()) {
return;
}
this.fireAppointmentResize({
appointment: oAppointment,
startDate: newPos.startDate,
endDate: newPos.endDate
});
setTimeout(function() {this.invalidate();}.bind(this), 0);
}.bind(this)
});
this.addDragDropConfig(oResizeConfig);
};
SinglePlanningCalendarGrid.prototype._configureAppointmentsCreate = function () {
this.addDragDropConfig(new DragDropInfo({
targetAggregation: "_intervalPlaceholders",
dragStart: function (oEvent) {
if (!this.getEnableAppointmentsCreate()) {
oEvent.preventDefault();
return;
}
var oBrowserEvent = oEvent.getParameter("browserEvent");
var $SPCGridOverlay = this.$().find(".sapMSinglePCOverlay");
setTimeout(function () {
$SPCGridOverlay.addClass("sapMSinglePCOverlayDragging");
});
jQuery(document).one("dragend", function () {
$SPCGridOverlay.removeClass("sapMSinglePCOverlayDragging");
jQuery(".sapUiAppCreate").remove();
jQuery(".sapUiDnDDragging").removeClass("sapUiDnDDragging");
});
oBrowserEvent.dataTransfer.setDragImage(getResizeGhost(), 0, 0);
var oGrid = oEvent.getParameter("target"),
bIsRtl = Configuration.getRTL(),
aIntervalPlaceholders = oGrid.getAggregation("_intervalPlaceholders"),
oFirstIntervalRectangle = aIntervalPlaceholders[0].getDomRef().getBoundingClientRect(),
iIntervalHeight = oFirstIntervalRectangle.height,
iIntervalIndexOffset = Math.floor((oFirstIntervalRectangle.top - oGrid.getDomRef().getBoundingClientRect().top) / iIntervalHeight),
oDragSession = oEvent.getParameter("dragSession"),
iIndexInColumn = Math.floor(oBrowserEvent.offsetY / iIntervalHeight) - iIntervalIndexOffset,
iIntervalIndex,
oCurrentIntervalBoundingRectangle;
if (this._iColumns === 1) {
iIntervalIndex = iIndexInColumn;
} else {
var iHeaderWidthSize = bIsRtl ? 0 : this.getDomRef().querySelector(".sapMSinglePCRowHeaders").getClientRects()[0].width,
iIntervalWidth = oGrid._aGridCells[0].getClientRects()[0].width,
iColumnsFromStart = Math.floor(Math.floor((oBrowserEvent.offsetX - iHeaderWidthSize)) / iIntervalWidth),
iIntervalsInColumn = aIntervalPlaceholders.length / this._iColumns;
iIntervalIndex = iIndexInColumn + ((iColumnsFromStart) * iIntervalsInColumn);
}
if (iIntervalIndex < 0) {
iIntervalIndex = 0;
}
oCurrentIntervalBoundingRectangle = aIntervalPlaceholders[iIntervalIndex].getDomRef().getBoundingClientRect();
oDragSession.setComplexData("startingRectsDropArea", {top: Math.ceil(iIndexInColumn * iIntervalHeight), left: oCurrentIntervalBoundingRectangle.left});
oDragSession.setComplexData("startingDropDate", aIntervalPlaceholders[iIntervalIndex].getDate());
}.bind(this),
dragEnter: function (oEvent) {
var oDragSession = oEvent.getParameter("dragSession"),
oDropControl = oDragSession.getDropControl(),
oDropDom = oDropControl.getDomRef(),
iDropHeight = oDropDom.offsetHeight,
iDropY = oDropDom.offsetTop,
iStartingDropY = iDropY,
iDropX = oDropDom.getBoundingClientRect().left,
iStartingDropX = iDropX,
oColumn = oDropControl.$().parents(".sapMSinglePCColumn").get(0),
$createPlaceHolder = jQuery(".sapUiAppCreate");
if (!$createPlaceHolder.get(0)) {
$createPlaceHolder = jQuery("<div></div>")
.addClass("sapUiCalendarApp sapUiCalendarAppType01 sapUiAppCreate");
$createPlaceHolder.appendTo(oColumn);
}
jQuery(".sapUiDnDDragging").removeClass("sapUiDnDDragging");
if (!oDragSession.getComplexData("startingRectsDropArea")) {
oDragSession.setComplexData("startingRectsDropArea", { top: iDropY, left: iDropX });
oDragSession.setComplexData("startingDropDate", oDropControl.getDate());
} else {
iStartingDropY = oDragSession.getComplexData("startingRectsDropArea").top;
iStartingDropX = oDragSession.getComplexData("startingRectsDropArea").left;
}
if (iDropX !== iStartingDropX) {
oEvent.preventDefault();
return false;
}
// Dim the column
oDropControl.$().closest(".sapMSinglePCColumn").find(".sapMSinglePCAppointments").addClass("sapUiDnDDragging");
$createPlaceHolder.css({
top: Math.min(iStartingDropY, iDropY) + 2,
height: Math.abs(iStartingDropY - iDropY) + iDropHeight - 4,
left: 3,
right: 3,
"z-index": 2
});
oDragSession.setIndicatorConfig({
display: "none"
});
},
drop: function (oEvent) {
var oDragSession = oEvent.getParameter("dragSession"),
oDropControl = oDragSession.getDropControl(),
iMillisecondsStep = (60 / (this.getScaleFactor() * 2)) * 60 * 1000, // calculating the duration of the appointment in milliseconds relative to the current scaleFactor
oStartDate = oDragSession.getComplexData("startingDropDate").getTime(),
oEndDate = oDropControl.getDate().getJSDate().getTime(),
iStartTime = Math.min(oStartDate, oEndDate),
iEndTime = Math.max(oStartDate, oEndDate) + iMillisecondsStep;
this.fireAppointmentCreate({
startDate: UI5Date.getInstance(iStartTime),
endDate: UI5Date.getInstance(iEndTime)
});
jQuery(".sapUiAppCreate").remove();
jQuery(".sapUiDnDDragging").removeClass("sapUiDnDDragging");
}.bind(this)
}));
};
SinglePlanningCalendarGrid.prototype._calcResizeNewHoursAppPos = function(oAppStartDate, oAppEndDate, iIndex, bBottomHandle) {
var iMinutesStep = (60 / (this.getScaleFactor() * 2)) * 60 * 1000, // calculating the duration of the appointment in milliseconds relative to the current scaleFactor
iPlaceholderStartTime = this.getAggregation("_intervalPlaceholders")[iIndex].getDate().getTime(),
iPlaceholderEndTime = iPlaceholderStartTime + iMinutesStep,
iVariableBoundaryTime = bBottomHandle ? oAppStartDate.getTime() : oAppEndDate.getTime(),
iStartTime = Math.min(iVariableBoundaryTime, iPlaceholderStartTime),
iEndTime = Math.max(iVariableBoundaryTime, iPlaceholderEndTime);
return {
startDate: UI5Date.getInstance(iStartTime),
endDate: UI5Date.getInstance(iEndTime)
};
};
SinglePlanningCalendarGrid.prototype._adjustAppointmentsHeightforCompact = function (sDate, oColumnStartDateAndHour, oColumnEndDateAndHour, iColumn) {
var oAppointment,
oAppDomRef,
oAppStartDate,
oAppEndDate,
iAppTop,
iAppBottom,
bAppStartIsOutsideVisibleStartHour,
bAppEndIsOutsideVisibleEndHour,
iRowHeight = this._getRowHeight(),
iRow = 0,
iVerticalPaddingBetweenAppointments = 0.125,
iAppointmentBottomPadding = 0.125,
iAppointmentTopPadding = 0.0625,
iScaleFactor = this.getScaleFactor(),
iDivider = 2 * iScaleFactor;
if (this._oAppointmentsToRender[sDate]) {
this._oAppointmentsToRender[sDate].oAppointmentsList.getIterator().forEach(function(oAppNode) {
oAppointment = oAppNode.getData();
oAppDomRef = this.getDomRef().querySelector("#" + oAppointment.getId() + "-" + iColumn + "_" + iRow);
oAppStartDate = oAppointment.getStartDate();
oAppEndDate = oAppointment.getEndDate();
bAppStartIsOutsideVisibleStartHour = oColumnStartDateAndHour.getTime() > oAppStartDate.getTime();
bAppEndIsOutsideVisibleEndHour = oColumnEndDateAndHour.getTime() < oAppEndDate.getTime();
iAppTop = bAppStartIsOutsideVisibleStartHour ? 0 : this._calculateTopPosition(oAppStartDate);
iAppBottom = bAppEndIsOutsideVisibleEndHour ? 0 : this._calculateBottomPosition(oAppEndDate);
oAppDomRef.style["top"] = iAppTop + "rem";
oAppDomRef.style["bottom"] = iAppBottom + "rem";
oAppDomRef.querySelector(".sapUiCalendarApp").style["minHeight"] = (iRowHeight - ((iVerticalPaddingBetweenAppointments + iAppointmentBottomPadding + iAppointmentTopPadding) * iScaleFactor)) / iDivider + "rem";
++iRow;
}.bind(this));
}
};
SinglePlanningCalendarGrid.prototype._adjustBlockersHeightforCompact = function () {
var iMaxLevel = this._getBlockersToRender().iMaxlevel,
iContainerHeight = (iMaxLevel + 1) * this._getBlockerRowHeight(),
// Day view has bigger height because of the day marker for special days
iRecalculatedContHeight = this._getColumns() === 1 ? iContainerHeight + DAY_MARKER_HEIGHT : iContainerHeight,
iBlockerRowHeight = this._getBlockerRowHeight();
if (iMaxLevel > 0) { // hackie thing to calculate the container witdth. When we have more than 1 line of blockers - we must add 0.1875rem in order to render the blockers visually in the container.
iRecalculatedContHeight = iRecalculatedContHeight + 0.1875;
}
this.$().find(".sapMSinglePCBlockersColumns").css("height", iRecalculatedContHeight + "rem");
this._oBlockersToRender.oBlockersList.getIterator().forEach(function(oBlockerNode) {
oBlockerNode.getData().$().css("top", (iBlockerRowHeight * oBlockerNode.level + 0.0625) + "rem");
});
};
/*
* Calculates the blocker column's height in the day view because of the special dates.
*/
SinglePlanningCalendarGrid.prototype._adjustBlockersHeightforCozy = function () {
var iMaxLevel = this._getBlockersToRender() && this._getBlockersToRender().iMaxlevel,
iContainerHeight;
if (this._getColumns() === 1) {
iContainerHeight = (iMaxLevel + 1) * this._getBlockerRowHeight();
this.$().find(".sapMSinglePCBlockersColumns").css("height", (iContainerHeight + DAY_MARKER_HEIGHT) + "rem");
}
};
SinglePlanningCalendarGrid.prototype._adjustRowHigth = function () {
this.$().find(".sapMSinglePCRow").css("height", this._getRowHeight() + "rem");
};
SinglePlanningCalendarGrid.prototype.onAfterRendering = function () {
var iColumns = this._getColumns(),
oStartDate = this.getStartDate(),
iRowHeight = this._getRowHeight();
if (iRowHeight === ROW_HEIGHT_COMPACT) {
for (var i = 0; i < iColumns; i++) {
var oColumnCalDate = new CalendarDate(oStartDate.getFullYear(), oStartDate.getMonth(), oStartDate.getDate() + i),
sDate = this._getDateFormatter().format(oColumnCalDate.toLocalJSDate()),
oColumnStartDateAndHour = new UniversalDate(oColumnCalDate.getYear(), oColumnCalDate.getMonth(), oColumnCalDate.getDate(), this._getVisibleStartHour()),
oColumnEndDateAndHour = new UniversalDate(oColumnCalDate.getYear(), oColumnCalDate.getMonth(), oColumnCalDate.getDate(), this._getVisibleEndHour(), 59, 59);
this._adjustAppointmentsHeightforCompact(sDate, oColumnStartDateAndHour, oColumnEndDateAndHour, i);
}
this._adjustBlockersHeightforCompact();
} else {
this._adjustBlockersHeightforCozy();
}
this._adjustRowHigth();
this._updateRowHeaderAndNowMarker();
_initItemNavigation.call(this);
};
/**
* Ensures that the focus is moved from an appointment to the correct cell from the visible grid area or
* borderReached event is fired when the correct cell to focus is outside of the visible grid area
* and removes the appointments selection.
*
* @param {object} oEvent The event object that is passed to the onsapup, onsapdown, onsapright, on sapleft handlers
* @param {int} iDirection Number representing the key code of the pressed arrow from the keyboard
* @private
*/
SinglePlanningCalendarGrid.prototype._appFocusHandler = function(oEvent, iDirection) {
var oTarget = sap.ui.getCore().byId(oEvent.target.id) || this._findSrcControl(oEvent);
if (oTarget && oTarget.isA("sap.ui.unified.CalendarAppointment")) {
this.fireAppointmentSelect({
appointment: undefined,
appointments: this._toggleAppointmentSelection(undefined, true)
});
this._focusCellWithKeyboard(oTarget, iDirection);
// Prevent scrolling
oEvent.preventDefault();
}
};
/**
* Ensures that the borderReached event is fired when the focus is on a cell and border is reached.
*
* @param {object} oEvent The event object that is passed to the onsapup, onsapdown, onsapright, on sapleft handlers
* @param {int} iDirection Number representing the key code of the pressed arrow from the keyboard
* @private
*/
SinglePlanningCalendarGrid.prototype._cellFocusHandler = function(oEvent, iDirection) {
var oGridCell = oEvent.target,
oFormat = this._getDateFormatter(),
oFocusedElement;
if (oGridCell.classList.contains("sapMSinglePCRow") ||
oGridCell.classList.contains("sapMSinglePCBlockersColumn")) {
oFocusedElement = oFormat.parse(oGridCell.getAttribute("data-sap-start-date"));
if (this._isBorderReached(oFocusedElement, iDirection)) {
this.fireEvent("borderReached", {
startDate: oFocusedElement,
next: iDirection === KeyCodes.ARROW_RIGHT,
fullDay: oGridCell.classList.contains("sapMSinglePCBlockersColumn")
});
}
}
};
SinglePlanningCalendarGrid.prototype.onsapup = function (oEvent) {
this._appFocusHandler(oEvent, KeyCodes.ARROW_UP);
};
SinglePlanningCalendarGrid.prototype.onsapdown = function (oEvent) {
this._appFocusHandler(oEvent, KeyCodes.ARROW_DOWN);
};
SinglePlanningCalendarGrid.prototype.onsapright = function (oEvent) {
this._appFocusHandler(oEvent, KeyCodes.ARROW_RIGHT);
this._cellFocusHandler(oEvent, KeyCodes.ARROW_RIGHT);
};
SinglePlanningCalendarGrid.prototype.onsapleft = function (oEvent) {
this._appFocusHandler(oEvent, KeyCodes.ARROW_LEFT);
this._cellFocusHandler(oEvent, KeyCodes.ARROW_LEFT);
};
SinglePlanningCalendarGrid.prototype.setStartDate = function (oStartDate) {
this._oOldStartDate = this.getStartDate();
this.getAggregation("_columnHeaders").setStartDate(oStartDate);
return this.setProperty("startDate", oStartDate);
};
// This function gets called from CalendarAppointment.prototype.applyFocusInfo function
// and therefore its only concern is the appointments focus in the SinglePlanningCalendarGrid
SinglePlanningCalendarGrid.prototype.applyFocusInfo = function (oFocusInfo) {
var aVisibleBlockers = this._getVisibleBlockers(),
oVisibleAppointments = this._getVisibleAppointments(),
aVisibleAppsKeys = Object.keys(oVisibleAppointments),
aVisibleAppsInDay,
i, j;
// directly focus appointment part, if there is any selected
if (this._sSelectedAppointment) {
this._sSelectedAppointment.focus();
return this;
}
// Search amongst the visible blockers
for (i = 0; i < aVisibleBlockers.length; ++i) {
if (aVisibleBlockers[i].getId() === oFocusInfo.id) {
aVisibleBlockers[i].focus();
return this;
}
}
// Search amongst the visible appointments
for (i = 0; i < aVisibleAppsKeys.length; ++i) {
aVisibleAppsInDay = oVisibleAppointments[aVisibleAppsKeys[i]];
for (j = 0; j < aVisibleAppsInDay.length; ++j) {
if (aVisibleAppsInDay[j].getId() === oFocusInfo.id) {
aVisibleAppsInDay[j].focus();
return this;
}
}
}
return this;
};
/**
* Holds the selected appointments. If no appointments are selected, an empty array is returned.
*
* @returns {sap.ui.unified.CalendarAppointment[]} All selected appointments
* @since 1.62
* @public
*/
SinglePlanningCalendarGrid.prototype.getSelectedAppointments = function() {
return this.getAppointments().filter(function(oAppointment) {
return oAppointment.getSelected();
});
};
SinglePlanningCalendarGrid.prototype.setDateSelectionMode = function (sSelectionMode){
this.setProperty("dateSelectionMode", sSelectionMode);
return this;
};
SinglePlanningCalendarGrid.prototype._isMultiDatesSelectionHeaderAllowed = function () {
return SinglePlanningCalendarSelectionMode.MultiSelect === this.getDateSelectionMode();
};
/*
* PRIVATE API
*/
/**
* Selects or deselects an appointment that is passed as a parameter. If it is selected, it is going to be
* deselected and vice versa. If modifier keys are pressed - the previously selected appointments will be
* preserved.
*
* @param {sap.m.CalendarAppointment} oAppointment The appointment to be selected/deselected.
* @param {boolean} [bRemoveOldSelection=false] If true, previously selected appointments will be deselected.
* @returns {array} Array of the appointments with changed selected state
* @private
*/
SinglePlanningCalendarGrid.prototype._toggleAppointmentSelection = function (oAppointment, bRemoveOldSelection) {
var aChangedApps = [],
oAppointmentDomRef = oAppointment && oAppointment.getDomRef(),
aAppointments,
iAppointmentsLength,
i;
if (bRemoveOldSelection) {
aAppointments = this.getAppointments();
for (i = 0, iAppointmentsLength = aAppointments.length; i < iAppointmentsLength; i++) {
// Deselecting all selected appointments if a grid cell is focused or
// all selected appointments different than the currently focused appointment
if ( (!oAppointment || aAppointments[i].getId() !== oAppointment.getId()) && aAppointments[i].getSelected()) {
aAppointments[i].setProperty("selected", false);
aChangedApps.push(aAppointments[i]);
}
}
}
if (oAppointment) {
oAppointment.setProperty("selected", !oAppointment.getSelected());
aChangedApps.push(oAppointment);
this._sSelectedAppointment = oAppointment.getSelected() && oAppointmentDomRef ? oAppointment : undefined;
} else {
this._sSelectedAppointment = undefined;
}
return aChangedApps;
};
/**
* Checking when an arrow key is pressed from the keyboard weather the cell focus should go in
* the next or previous day or week
*
* @param {Date} oFocusedElement The start date of the focused cell or of the visible part of the appointment
* @param {int} iDirection The key the was pressed
* @returns {boolean} Indicator if the gird border is reached
* @private
*/
SinglePlanningCalendarGrid.prototype._isBorderReached = function(oFocusedElement, iDirection) {
var oGridStartDate = CalendarDate.fromLocalJSDate(this.getStartDate()),
oGridEndDate = new CalendarDate(oGridStartDate.getYear(), oGridStartDate.getMonth(), oGridStartDate.getDate() + this._getColumns() - 1),
oTargetStartDate = CalendarDate.fromLocalJSDate(oFocusedElement),
bLeft = iDirection === KeyCodes.ARROW_LEFT && oTargetStartDate.isSame(oGridStartDate),
bRight = iDirection === KeyCodes.ARROW_RIGHT && oTargetStartDate.isSame(oGridEndDate);
return bLeft || bRight;
};
/**
* Ensures that the focus is moved from an appointment to the correct cell from the visible grid area or
* borderReached event is fired when the correct cell to focus is outside of the visible grid area.
*
* @param {sap.ui.unified.CalendarAppointment} oAppointment Appointment from which to start navigation
* @param {int} iDirection Number representing the key code of the pressed arrow from the keyboard
* @private
*/
SinglePlanningCalendarGrid.prototype._focusCellWithKeyboard = function (oAppointment, iDirection) {
var bFullDayApp = this.isAllDayAppointment(oAppointment.getStartDate(), oAppointment.getEndDate()),
oFormat = this._getDateFormatter(),
oAppStartDate = UI5Date.getInstance(oAppointment.getStartDate().getFullYear(), oAppointment.getStartDate().getMonth(), oAppointment.getStartDate().getDate(), oAppointment.getStartDate().getHours()),
oGridStartDate = UI5Date.getInstance(this.getStartDate().getFullYear(), this.getStartDate().getMonth(), this.getStartDate().getDate(), this.getStartDate().getHours());
// If an appointment start hour is before the visible grid start date
// we will use the grid start date as the appointment start date.
if (oAppStartDate < oGridStartDate) {
oAppStartDate = oGridStartDate;
}
if (this._isBorderReached(oAppStartDate, iDirection)) {
this.fireEvent("borderReached", {
startDate: oAppStartDate,
next: iDirection === KeyCodes.ARROW_RIGHT,
fullDay: bFullDayApp
});
return;
}
switch (iDirection) {
case KeyCodes.ARROW_UP:
if (!bFullDayApp) {
oAppStartDate.setHours(oAppStartDate.getHours() - 1);
}
break;
case KeyCodes.ARROW_DOWN:
if (!bFullDayApp) {
oAppStartDate.setHours(oAppStartDate.getHours() + 1);
}
break;
case KeyCodes.ARROW_LEFT:
oAppStartDate.setDate(oAppStartDate.getDate() - 1);
break;
case KeyCodes.ARROW_RIGHT:
oAppStartDate.setDate(oAppStartDate.getDate() + 1);
break;
default:
}
if (bFullDayApp && iDirection !== KeyCodes.ARROW_DOWN) {
jQuery("[data-sap-start-date='" + oFormat.format(oAppStartDate) + "'].sapMSinglePCBlockersColumn").trigger("focus");
} else {
jQuery("[data-sap-start-date='" + oFormat.format(oAppStartDate) + "'].sapMSinglePCRow").trigger("focus");
}
};
SinglePlanningCalendarGrid.prototype.onmouseup = function (oEvent) {
var bMultiDateSelection = SinglePlanningCalendarSelectionMode.MultiSelect === this.getDateSelectionMode();
if (!bMultiDateSelection && !(oEvent.metaKey || oEvent.ctrlKey)) {
this.removeAllSelectedDates();
}
this._bMultiDateSelect = true;
this._fireSelectionEvent(oEvent);
};
/**
* Handles the <code>tap</code> event on the grid.
*
* @param {jQuery.Event} oEvent The event object
*/
SinglePlanningCalendarGrid.prototype.ontap = function (oEvent) {
this._fireSelectionEvent(oEvent);
};
SinglePlanningCalendarGrid.prototype.removeAllSelectedDates = function(oEvent) {
this.removeAllAggregation("selectedDates");
};
/**
* Handles the <code>keyup</code> event.
*
* @param {jQuery.Event} oEvent The event object.
*/
SinglePlanningCalendarGrid.prototype.onkeyup = function(oEvent) {
var bMultiDateSelection = SinglePlanningCalendarSelectionMode.MultiSelect === this.getDateSelectionMode();
if ((oEvent.which === KeyCodes.ARROW_LEFT || oEvent.which === KeyCodes.ARROW_RIGHT) && oEvent.shiftKey && bMultiDateSelection) {
this._bMultiDateSelectWithArrow = true;
} else if (oEvent.which === KeyCodes.SPACE && !oEvent.shiftKey && bMultiDateSelection) {
this._bMultiDateSelect = true;
}
this._fireSelectionEvent(oEvent);
// Prevent scrolling
oEvent.preventDefault();
};
/**
* Handles the <code>keydown</code> event when any key is pressed.
*
* @param {jQuery.Event} oEvent The event object.
*/
SinglePlanningCalendarGrid.prototype.onkeydown = function (oEvent) {
var bMultiDateSelection = SinglePlanningCalendarSelectionMode.MultiSelect === this.getDateSelectionMode();
if (oEvent.which === KeyCodes.SPACE || oEvent.which === KeyCodes.ENTER ||
oEvent.which === KeyCodes.ARROW_LEFT || oEvent.which === KeyCodes.ARROW_RIGHT) {
if (oEvent.which === KeyCodes.SPACE && oEvent.shiftKey && bMultiDateSelection) {
this._bCurrentWeekSelection = true;
}
this._fireSelectionEvent(oEvent);
var oControl = this._findSrcControl(oEvent);
if (oContr