@openui5/sap.m
Version:
OpenUI5 UI Library sap.m
865 lines (750 loc) • 27.8 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
// Provides control sap.m.PlanningCalendarHeader.
sap.ui.define([
'./library',
'./Toolbar',
'./AssociativeOverflowToolbar',
'./Button',
'./AdditionalTextButton',
'./Popover',
'./Title',
'./ToolbarSpacer',
'./Label',
'./OverflowToolbarLayoutData',
'./SegmentedButton',
'./PlanningCalendarHeaderRenderer',
'sap/ui/core/Lib',
'sap/ui/core/Element',
'sap/ui/core/Control',
'sap/ui/unified/Calendar',
'sap/ui/unified/calendar/CustomMonthPicker',
'sap/ui/unified/calendar/CustomYearPicker',
'sap/ui/unified/calendar/IndexPicker',
'sap/base/i18n/date/CalendarType',
'sap/base/i18n/date/CalendarWeekNumbering',
'sap/base/i18n/Localization',
'sap/ui/core/IconPool',
'sap/ui/core/InvisibleText',
'sap/ui/core/library',
'sap/ui/core/date/UI5Date'
],
function(
library,
Toolbar,
AssociativeOverflowToolbar,
Button,
AdditionalTextButton,
Popover,
Title,
ToolbarSpacer,
Label,
OverflowToolbarLayoutData,
SegmentedButton,
PlanningCalendarHeaderRenderer,
Library,
Element,
Control,
Calendar,
CustomMonthPicker,
CustomYearPicker,
IndexPicker,
_CalendarType, // type of `_primaryCalendarType` and `_secondaryCalendarType`
_CalendarWeekNumbering, // type of `calendarWeekNumbering`
Localization,
IconPool,
InvisibleText,
coreLibrary,
UI5Date
) {
"use strict";
/**
* Constructor for a new <code>PlanningCalendarHeader</code>.
*
* @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
* Disclaimer: This control is in a beta state - incompatible API changes may be done before its official public
* release. Use at your own discretion.
*
* <h3>Overview</h3>
*
* The calendar header contains the action controls which you can use to manipulate the calendar and facilitate
* navigation.
*
* <b>Note:</b> The <code>PlanningCalendarHeader</code> uses parts of the <code>sap.ui.unified</code> library.
* This library will be loaded after the <code>PlanningCalendarHeader</code>, if it wasn't previously loaded.
* This could lead to a waiting time when a <code>PlanningCalendarHeader</code> is used for the first time.
* To prevent this, apps using the <code>PlanningCalendarHeader</code> must also load the
* <code>sap.ui.unified</code> library.
*
* <h3>Usage</h3>
*
* The <code>PlanningCalendarHeader</code> has the following structure:
*
* It contains two toolbars.
* <ul>
* <li>The title of the control, set from the <code>title</code> property, is placed at the beginning
* of the first toolbar. If there is more than one view, the user can switch between the views using the
* <code>SegmentedButton</code>, displayed afterwards. If controls in the <code>actions</code>
* aggregation are set, they will be displayed at the end.</li>
* <li>Navigation in the second toolbar will help the user select the desired time period.
* It contains navigation arrows, Today button and a calendar picker.</li>
* </ul>
*
* @extends sap.ui.core.Control
*
* @author SAP SE
* @version 1.146.0
*
* @constructor
* @private
* @since 1.61
* @alias sap.m.PlanningCalendarHeader
*/
var PlanningCalendarHeader = Control.extend("sap.m.PlanningCalendarHeader", /** @lends sap.m.PlanningCalendarHeader.prototype */ {
metadata : {
library : "sap.m",
properties : {
/**
* Determines the start date used in the calendar picker, 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 text of the button which opens the calendar picker.
*/
pickerText : { type : "string", group : "Data" },
/**
* Determines the additional text of the button which opens the calendar picker.
*/
pickerTextInSecondaryType : { type : "string", group : "Data" },
/**
* Defines the calendar week numbering used for display.
* @private
* @ui5-restricted sap.m.PlanningCalendarHeader
* @since 1.110.0
*/
calendarWeekNumbering : { type : "sap.base.i18n.date.CalendarWeekNumbering", group : "Appearance", defaultValue: null},
/**
* If set, the calendar type is used for display.
* If not set, the calendar type of the global configuration is used.
* @private
* @ui5-restricted sap.m.PlanningCalendarHeader
* @since 1.108.0
*/
_primaryCalendarType : {type : "sap.base.i18n.date.CalendarType", group : "Appearance"},
/**
* If set, the days are also displayed in this calendar type
* If not set, the dates are only displayed in the primary calendar type
* @private
* @ui5-restricted sap.m.PlanningCalendarHeader
* @since 1.109.0
*/
_secondaryCalendarType : {type : "sap.base.i18n.date.CalendarType", group : "Appearance"}
},
aggregations : {
/**
* The controls to be passed to the toolbar.
*/
actions : { type : "sap.ui.core.Control", multiple: true, singularName: "action" },
/**
* Hidden, for internal use only.
* The toolbar which contains the title, the SegmentedButton for the views and the controls from the actions aggregation.
*
* @private
*/
_actionsToolbar : { type: "sap.m.OverflowToolbar", multiple: false, visibility : "hidden" },
/**
* Hidden, for internal use only.
* The toolbar which contains the navigation inner controls.
*
* @private
*/
_navigationToolbar : { type: "sap.m.Toolbar", multiple: false, visibility : "hidden" },
/**
* Hidden, for internal use only.
* The popup which contains the calendar for navigation.
*
* @private
*/
_calendarPicker : { type : "sap.ui.unified.Calendar", multiple : false, visibility : "hidden" },
/**
* Hidden, for internal use only.
* The popup which contains the month picker for navigation.
*
* @private
*/
_monthPicker : { type : "sap.ui.unified.internal.CustomMonthPicker", multiple : false, visibility : "hidden" },
/**
* Hidden, for internal use only.
* The popup which contains the year picker for navigation.
*
* @private
*/
_yearPicker : { type : "sap.ui.unified.internal.CustomYearPicker", multiple : false, visibility : "hidden" },
/**
* Hidden, for internal use only.
* The popup which contains the index picker for navigation.
*
* @private
*/
_indexPicker : { type : "sap.ui.unified.calendar.IndexPicker", multiple : false, visibility : "hidden" }
},
events : {
/**
* <code>startDate</code> was changed while navigating backward in the <code>PlanningCalendarHeader</code>.
* The new value can be obtained, using the <code>sap.m.PlanningCalendarHeader#getStartDate()</code> method.
*/
pressPrevious: {},
/**
* <code>startDate</code> was changed while navigating through the Today button in the
* <code>PlanningCalendarHeader</code>.
* The new value can be obtained, using the <code>sap.m.PlanningCalendarHeader#getStartDate()</code> method.
*/
pressToday: {},
/**
* <code>startDate</code> was changed while navigating forward in the <code>PlanningCalendarHeader</code>.
* The new value can be obtained, using the <code>sap.m.PlanningCalendarHeader#getStartDate()</code> method.
*/
pressNext: {},
/**
* A date was selected through the calendar picker.
* The new value can be obtained, using the <code>sap.m.PlanningCalendarHeader#getStartDate()</code> method.
*/
dateSelect: {},
/**
* The calendar picker popup was closed and no date was selected.
*/
cancel: {},
/**
* The view was changed by user interaction.
*/
viewChange : {}
},
associations: {
/**
* Association to control / ID which is shown in the picker popup.
* @since 1.70.0
*/
currentPicker: { type: "sap.ui.core.Control", multiple: false }
}
},
renderer: PlanningCalendarHeaderRenderer
});
// Number of items to be skipped when removing content from actions aggregation.
// In the _actionsToolbar content are placed the sap.m.Title control,
// a sap.m.ToolbarSpacer, sap.m.Label and a sap.m.SegmentedButton, used for navigation through the views in the calendar.
// The other controls in this aggregation are forwarded from the actions aggregation of the
// sap.m.SinglePlanningCalendar. Therefore when manipulations of the latter are needed, the first four controls
// must be skipped. (ex. when removeAllActions is used)
const RESERVED_ACTIONS_ITEMS_COUNT = 4;
PlanningCalendarHeader.prototype.init = function() {
const sOPHId = this.getId(),
sNavToolbarId = sOPHId + "-NavToolbar",
oRB = Library.getResourceBundleFor("sap.m"),
sCalendarType = this.getProperty("_primaryCalendarType");
this.setAggregation("_actionsToolbar", new AssociativeOverflowToolbar(sOPHId + "-ActionsToolbar", {})
.addStyleClass("sapMPCHeadActionsToolbar")
.addContent(this._getOrCreateTitleControl())
.addContent(this._getOrCreateToolbarSpacer())
.addContent(this._getOrCreateViewSwitchLabel())
.addContent(this._getOrCreateViewSwitch())
);
this._oPrevBtn = new Button(sNavToolbarId + "-PrevBtn", {
icon: IconPool.getIconURI('slim-arrow-left'),
tooltip: oRB.getText("PCH_NAVIGATE_BACKWARDS"),
press: function () {
this.firePressPrevious();
}.bind(this)
});
this._oTodayBtn = new Button(sNavToolbarId + "-TodayBtn", {
text: oRB.getText("PLANNINGCALENDAR_TODAY"),
ariaLabelledBy: InvisibleText.getStaticId("sap.m", "PCH_NAVIGATE_TO_TODAY"),
press: function () {
this.firePressToday();
}.bind(this)
});
this._oNextBtn = new Button(sNavToolbarId + "-NextBtn", {
icon: IconPool.getIconURI('slim-arrow-right'),
tooltip: oRB.getText("PCH_NAVIGATE_FORWARD"),
press: function () {
this.firePressNext();
}.bind(this)
});
const oCalendarPicker = new Calendar(sOPHId + "-Cal", {
calendarWeekNumbering: this.getCalendarWeekNumbering(),
primaryCalendarType: sCalendarType
});
oCalendarPicker.attachEvent("select", this._handlePickerDateSelect, this);
oCalendarPicker.attachEvent("cancel", this._handlePickerCancelEvent, this);
this.setAggregation("_calendarPicker", oCalendarPicker);
this._oCalendarAfterRenderDelegate = {
onAfterRendering: function() {
if (this._oPopup && this._oPopup.isOpen()) {
oCalendarPicker.focus();
}
}.bind(this)
};
oCalendarPicker.addDelegate(this._oCalendarAfterRenderDelegate);
this._oCalendar = oCalendarPicker;
this.setAssociation("currentPicker", oCalendarPicker);
const oMonthPicker = new CustomMonthPicker(sOPHId + "-MonthCal", {
primaryCalendarType: sCalendarType
});
oMonthPicker.attachEvent("select", this._handlePickerDateSelect, this);
oMonthPicker.attachEvent("cancel", this._handlePickerCancelEvent, this);
this.setAggregation("_monthPicker", oMonthPicker);
this._oMonthPicker = oMonthPicker;
const oYearPicker = new CustomYearPicker(sOPHId + "-YearCal", {
primaryCalendarType: sCalendarType
});
oYearPicker.attachEvent("select", this._handlePickerDateSelect, this);
oYearPicker.attachEvent("cancel", this._handlePickerCancelEvent, this);
this.setAggregation("_yearPicker", oYearPicker);
this._oYearPicker = oYearPicker;
const oIndexPicker = new IndexPicker(sOPHId + "-IndexPicker");
oIndexPicker.attachEvent("select", this._handleIndexPickerSelect, this);
this.setAggregation("_indexPicker", oIndexPicker);
this._oIndexPicker = oIndexPicker;
this._oPickerBtn = new AdditionalTextButton(sNavToolbarId + "-PickerBtn", {
text: this.getPickerText(),
additionalText: this.getPickerTextInSecondaryType(),
ariaHasPopup: coreLibrary.aria.HasPopup.Dialog,
ariaLabelledBy: InvisibleText.getStaticId("sap.m", "PCH_SELECT_RANGE"),
press: function () {
if (this.fireEvent("_pickerButtonPress", {}, true)) {
let oDate = this.getStartDate() || UI5Date.getInstance(),
oMinDate;
const sCurrentPickerId = this.getAssociation("currentPicker");
const oPicker = Element.getElementById(sCurrentPickerId);
if (oPicker instanceof Calendar) {
oMinDate = oPicker.getMinDate();
if (oMinDate && oMinDate.getTime() > oDate.getTime()) {
oDate = oMinDate;
}
}
if (oPicker.displayDate) {
oPicker.displayDate(oDate);
}
oPicker.setCalendarWeekNumbering && oPicker.setCalendarWeekNumbering(this.getCalendarWeekNumbering());
this._openCalendarPickerPopup(oPicker);
}
}.bind(this)
});
this.setAggregation("_navigationToolbar", new Toolbar(sNavToolbarId, {
content: [
this._oPrevBtn,
this._oTodayBtn,
this._oNextBtn,
this._oPickerBtn
]
}).addStyleClass("sapMPCHeadNavToolbar"));
};
PlanningCalendarHeader.prototype.exit = function () {
this._getActionsToolbar().removeAllContent();
if (this._oDefaultTitle) {
this._oDefaultTitle.destroy();
this._oDefaultTitle = null;
}
if (this._oTitle) {
this._oTitle.destroy();
this._oTitle = null;
}
if (this._oToolbarSpacer) {
this._oToolbarSpacer.destroy();
this._oToolbarSpacer = null;
}
if (this._oViewSwitch) {
this._oViewSwitch.destroy();
this._oViewSwitch = null;
}
if (this._oViewSwitchLabel) {
this._oViewSwitchLabel.destroy();
this._oViewSwitchLabel = null;
}
if (this._oPopup) {
if (this._oCalendarAfterRenderDelegate) {
this._oCalendar.removeDelegate(this._oCalendarAfterRenderDelegate);
}
this._oPopup.destroy();
this._oPopup = null;
}
if (this._oPrevBtn) {
this._oPrevBtn.destroy();
this._oPrevBtn = null;
}
if (this._oNextBtn) {
this._oNextBtn.destroy();
this._oNextBtn = null;
}
};
PlanningCalendarHeader.prototype.onBeforeRendering = function () {
const bVisibleTitle = this.getAggregation("_actionsToolbar").getContent()[0].getVisible();
const oViewSwitch = this._getOrCreateViewSwitch();
const bVisible = !!this.getActions().length || bVisibleTitle || oViewSwitch.getItems().length > 1;
const sSecondaryCalendarType = this.getProperty("_secondaryCalendarType");
this._getActionsToolbar().setVisible(bVisible);
this.setPrimaryCalendarTypeToPickers(this.getProperty("_primaryCalendarType"));
if (sSecondaryCalendarType){
this.setSecondaryCalendarTypeToPickers(sSecondaryCalendarType);
}
};
PlanningCalendarHeader.prototype._changeTitle = function (oTitle) {
this.fireEvent("_titleChange", { title: oTitle }, true, this);
const oCurrentTitle = this._getActionsToolbar().getContent()[0];
this._getActionsToolbar().removeContent(oCurrentTitle);
return this._getActionsToolbar().insertContent(oTitle, 0);
};
PlanningCalendarHeader.prototype.addAction = function (oAction) {
if (!oAction) {
return this;
}
if (oAction.isA("sap.m.Title")) {
this._changeTitle(oAction);
this._oTitle = oAction;
} else {
this._getActionsToolbar().addContent(oAction);
}
return this.addAggregation("actions", oAction);
};
PlanningCalendarHeader.prototype.insertAction = function (oAction, iIndex) {
if (!oAction) {
return this;
}
if (oAction.isA("sap.m.Title")) {
this._oTitle = oAction;
return this._changeTitle(oAction);
}
this._getActionsToolbar().insertContent(oAction, iIndex + RESERVED_ACTIONS_ITEMS_COUNT);
return this.insertAggregation("actions", oAction, iIndex);
};
PlanningCalendarHeader.prototype.removeAction = function (oAction) {
if (!oAction) {
return this;
}
if (oAction.isA("sap.m.Title") && this._oTitle === oAction) {
this._oTitle = null;
this._changeTitle(this._getOrCreateTitleControl());
}
this._getActionsToolbar().removeContent(oAction);
return this.removeAggregation("actions", oAction);
};
PlanningCalendarHeader.prototype.getTitle = function () {
if (this._oTitle) {
return this._oTitle;
}
return this._getOrCreateTitleControl();
};
PlanningCalendarHeader.prototype.removeAllActions = function () {
var oActionsToolbar = this._getActionsToolbar(),
oActionsToolbarContent = oActionsToolbar.getContent();
if (oActionsToolbarContent[0] === this._oTitle) {
this._oTitle = null;
this._changeTitle(this._getOrCreateTitleControl());
}
for (var i = RESERVED_ACTIONS_ITEMS_COUNT; i < oActionsToolbarContent.length; i++) {
oActionsToolbar.removeContent(oActionsToolbarContent[i]);
}
return this.removeAllAggregation("actions");
};
PlanningCalendarHeader.prototype.destroyActions = function () {
const oActionsToolbar = this._getActionsToolbar(),
oActionsToolbarContent = oActionsToolbar.getContent();
for (var i = RESERVED_ACTIONS_ITEMS_COUNT; i < oActionsToolbarContent.length; i++) {
const oRemovedContentItem = oActionsToolbar.removeContent(oActionsToolbarContent[i]);
oRemovedContentItem.destroy();
}
return this;
};
PlanningCalendarHeader.prototype.updatePickerText = function (oPickerTextInfo) {
if (!oPickerTextInfo) {
return this;
}
this.setPickerText(oPickerTextInfo.primaryType);
this.setPickerTextInSecondaryType(oPickerTextInfo.secondaryType);
return true;
};
PlanningCalendarHeader.prototype.setPickerTextInSecondaryType = function (sAdditionalText){
this.setProperty("pickerTextInSecondaryType", sAdditionalText);
this._oPickerBtn.setAdditionalText(sAdditionalText);
return this;
};
PlanningCalendarHeader.prototype.setPickerText = function (sText) {
if (!sText) {
return this;
}
this.setProperty("pickerText", sText);
this._oPickerBtn.setText(sText);
return this;
};
PlanningCalendarHeader.prototype.setPrimaryCalendarTypeToPickers = function (sCalendarType) {
this._oCalendar.setPrimaryCalendarType(sCalendarType);
this._oMonthPicker.setPrimaryCalendarType(sCalendarType);
this._oYearPicker.setPrimaryCalendarType(sCalendarType);
};
PlanningCalendarHeader.prototype.setSecondaryCalendarTypeToPickers = function (sCalendarType) {
this._oCalendar.setSecondaryCalendarType(sCalendarType);
this._oMonthPicker.setSecondaryCalendarType(sCalendarType);
this._oYearPicker.setSecondaryCalendarType(sCalendarType);
};
/**
* If not existing yet, creates the inner Title control.
* Otherwise just returns it.
* @returns {sap.m.Title} The title object
* @private
*/
PlanningCalendarHeader.prototype._getOrCreateTitleControl = function () {
if (!this._oDefaultTitle) {
this._oDefaultTitle = new Title(this.getId() + "-Title", { visible: false });
}
return this._oDefaultTitle;
};
/**
* If not existing yet, creates the inner ToolbarSpacer control.
* Otherwise just returns it.
* @returns {sap.m.ToolbarSpacer} The ToolbarSpacer object
* @private
*/
PlanningCalendarHeader.prototype._getOrCreateToolbarSpacer = function () {
if (!this._oToolbarSpacer) {
this._oToolbarSpacer = new ToolbarSpacer(this.getId() + "-Spacer");
}
return this._oToolbarSpacer;
};
/**
* If not existing yet, creates the inner SegmentedButton control, which controls the views.
* Otherwise just returns it.
* @returns {sap.m.SegmentedButton} The SegmentedButton object
* @private
*/
PlanningCalendarHeader.prototype._getOrCreateViewSwitch = function () {
if (!this._oViewSwitch) {
this._oViewSwitch = new SegmentedButton(this.getId() + "-ViewSwitch", {
layoutData: new OverflowToolbarLayoutData({
group: 1,
priority: library.OverflowToolbarPriority.High
})
});
this._oViewSwitch.attachEvent("selectionChange", this._handleViewSwitchChange, this);
this.addDependent(this._oViewSwitch);
}
return this._oViewSwitch;
};
PlanningCalendarHeader.prototype._getOrCreateViewSwitchLabel = function () {
if (!this._oViewSwitchLabel) {
this._oViewSwitchLabel = new Label(this.getId() + "-ViewSwitchLabel", {
text: Library.getResourceBundleFor("sap.m").getText("PCH_VIEW_SWITCH"),
visible: false, // Start invisible, will be shown only in select mode
layoutData: new OverflowToolbarLayoutData({
group: 1,
priority: library.OverflowToolbarPriority.High
})
});
this.addDependent(this._oViewSwitchLabel);
}
return this._oViewSwitchLabel;
};
/**
* Converts the view switch from sap.m.SegmentedButton to sap.m.Select.
* @private
*/
PlanningCalendarHeader.prototype._convertViewSwitchToSelect = function () {
this._oViewSwitch._bForcedSelectMode = true;
this._oViewSwitch._toSelectMode();
this._updateViewSwitchLabelFor();
};
/**
* Converts the view switch from sap.m.Select to sap.m.SegmentedButton
* @private
*/
PlanningCalendarHeader.prototype._convertViewSwitchToSegmentedButton = function () {
this._oViewSwitch._bForcedSelectMode = false;
this._oViewSwitch._toNormalMode();
this._updateViewSwitchLabelFor();
};
/**
* Updates the labelFor property of the view switch label to reference the correct element
* depending on whether the view switch is in SegmentedButton or Select mode.
* Also controls label visibility - only show when in select mode.
* @private
*/
PlanningCalendarHeader.prototype._updateViewSwitchLabelFor = function () {
const oViewSwitch = this._getOrCreateViewSwitch();
const oViewSwitchLabel = this._getOrCreateViewSwitchLabel();
// Check if the SegmentedButton is in overflow mode (select mode)
// Use _bInOverflow property first, fallback to CSS class check for robustness
const bIsSelectMode = oViewSwitch._bInOverflow || oViewSwitch.hasStyleClass("sapMSegBSelectWrapper");
if (bIsSelectMode) {
// In select mode (overflow): show label and set labelFor to select element
oViewSwitchLabel.setVisible(true);
oViewSwitchLabel.setLabelFor(oViewSwitch.getId() + "-select");
} else {
// In normal SegmentedButton mode: hide label and clear labelFor
oViewSwitchLabel.setVisible(false);
oViewSwitchLabel.setLabelFor("");
}
};
/**
* Returns the today button control.
*
* @returns {sap.m.Button} The today button
* @private
*/
PlanningCalendarHeader.prototype._getTodayButton = function () {
return this._oTodayBtn;
};
/**
* Handler for the select event of the current picker.
* @private
*/
PlanningCalendarHeader.prototype._handlePickerDateSelect = function () {
const sCurrentPickerId = this.getAssociation("currentPicker"),
oPicker = Element.getElementById(sCurrentPickerId),
oSelectedDate = oPicker.getSelectedDates()[0].getStartDate();
this.setStartDate(oSelectedDate);
this._closeCalendarPickerPopup();
this.fireDateSelect();
// TODO: Focus should be returned to the picker after selection.
//oPickerBtnDomRef && oPickerBtnDomRef.focus();
};
PlanningCalendarHeader.prototype._handleIndexPickerSelect = function (oEvent) {
const iSelectedIndex = this._oIndexPicker.getSelectedIndex();
const oSelectedDate = UI5Date.getInstance(this._oCalendar.getMinDate());
const oRelativeInfo = this._getRelativeInfo();
oSelectedDate.setDate(oSelectedDate.getDate() + iSelectedIndex * oRelativeInfo.iIntervalSize);
this.setStartDate(oSelectedDate);
this._closeCalendarPickerPopup();
this.fireDateSelect();
};
/**
* Handler for the change event of the view switch.
* @private
*/
PlanningCalendarHeader.prototype._handleViewSwitchChange = function (oEvent) {
this.fireViewChange(oEvent.getParameters());
};
/**
* Opens the picker popup, when the picker button from the _navigationToolbar is pressed.
* @param {object} oPicker The picker to be opened
* @private
*/
PlanningCalendarHeader.prototype._openCalendarPickerPopup = function(oPicker){
if (!this._oPopup) {
this._oPopup = this._createPopup();
}
const aContent = this._oPopup.getContent();
const sAccessibleNameId = InvisibleText.getStaticId("sap.m", this._getPopoverAccessibleName());
this._oPopup.removeAllAssociation("ariaLabelledBy");
this._oPopup.addAriaLabelledBy(sAccessibleNameId);
if (aContent.length) {
const oContent = this._oPopup.getContent()[0];
if (oContent.isA("sap.ui.unified.internal.CustomYearPicker")) {
this.setAggregation("_yearPicker", this._oPopup.removeAllContent()[0]);
} else if (oContent.isA("sap.ui.unified.internal.CustomMonthPicker")) {
this.setAggregation("_monthPicker", this._oPopup.removeAllContent()[0]);
} else if (oContent.isA("sap.ui.unified.calendar.IndexPicker")) {
this.setAggregation("_indexPicker", this._oPopup.removeAllContent()[0]);
} else if (oPicker !== oContent) {
this.setAggregation("_calendarPicker", this._oPopup.removeAllContent()[0]);
}
}
this._oPopup.addContent(oPicker);
this._oPopup.attachAfterOpen(function () {
const $Popover = this._oPopup.$();
const iOffsetX = Math.floor(($Popover.width() - this._oPickerBtn.$().width()) / 2);
this._oPopup.setOffsetX(Localization.getRTL() ? iOffsetX : -iOffsetX);
const iOffsetY = this._oPickerBtn.$().height();
this._oPopup.setOffsetY(this._oPopup._getCalculatedPlacement() === "Top" ? iOffsetY : -iOffsetY);
this._oPopup.getContent()[0].focus();
}, this);
this._oPopup.openBy(this._oPickerBtn.getDomRef());
};
/**
* Creates the picker popup.
* @returns {sap.m.Popover} the created popup
* @private
*/
PlanningCalendarHeader.prototype._createPopup = function () {
const oPopover = new Popover({
placement: "VerticalPreferredBottom",
showHeader: false,
showArrow: false,
verticalScrolling: false
});
oPopover.oPopup.setDurations(0, 0); // no animations
oPopover.addDelegate({
onsapescape: this.onsapescape
}, this);
this._oPopup = oPopover;
return this._oPopup;
};
/**
* Returns the message bundle key of the invisible text for the accessible name of the popover.
* @private
* @returns {string} The message bundle key
*/
PlanningCalendarHeader.prototype._getPopoverAccessibleName = function() {
const sPickerName = Element.getElementById(this.getAssociation("currentPicker")).getMetadata().getName();
switch (sPickerName) {
case "sap.ui.unified.internal.CustomYearPicker":
return "DATEPICKER_YEAR_POPOVER_ACCESSIBLE_NAME";
case "sap.ui.unified.internal.CustomMonthPicker":
return "DATEPICKER_MONTH_POPOVER_ACCESSIBLE_NAME";
default:
return "DATEPICKER_POPOVER_ACCESSIBLE_NAME";
}
};
/**
* Closes the picker popup without setting new startDate to the PlanningCalendarHeader.
* @private
*/
PlanningCalendarHeader.prototype.onsapescape = function(){
if (this._oPopup) {
this._closeCalendarPickerPopup();
if (this._oPickerBtn.getDomRef()) {
this._oPickerBtn.getDomRef().focus();
}
}
};
/**
* Closes the picker popup.
* @private
*/
PlanningCalendarHeader.prototype._closeCalendarPickerPopup = function() {
if (this._oPopup && this._oPopup.isOpen()) {
this._oPopup.close();
}
};
/**
* Fires cancel on the picker popup.
* @private
*/
PlanningCalendarHeader.prototype._handlePickerCancelEvent = function () {
const oPickerBtnDomRef = this._oPickerBtn.getDomRef();
this.fireCancel();
this._closeCalendarPickerPopup();
oPickerBtnDomRef && oPickerBtnDomRef.focus();
};
/**
* Getter for _actionsToolbar.
* @returns {object} The _actionsToolbar object
* @private
*/
PlanningCalendarHeader.prototype._getActionsToolbar = function () {
return this.getAggregation("_actionsToolbar");
};
/**
* Getter for _navigationToolbar.
* @returns {object} The _navigationToolbar object
* @private
*/
PlanningCalendarHeader.prototype._getNavigationToolbar = function () {
return this.getAggregation("_navigationToolbar");
};
return PlanningCalendarHeader;
});