@openui5/sap.m
Version:
OpenUI5 UI Library sap.m
335 lines (292 loc) • 12.3 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.
*/
/**
* OverflowToolbar / OverflowToolbarAssociativePopover helper
* This class handles the changes done to controls with respect to the associative popover
* For each control that must have a special handling before entering/leaving the popover, there must be 2 functions:
* _preProcessCONTROL (called before moving the control to the popover)
* _postProcessCONTROL (called before returning the control to the toolbar)
* where CONTROL is a camel-cased version of the getMetadata().getName() value, f.e. "sap.m.Button" becomes "sapMButton"
*/
sap.ui.define([
'sap/ui/base/Object',
'./OverflowToolbarButton',
'./OverflowToolbarMenuButton',
'./OverflowToolbarToggleButton',
'./ToggleButton',
'./Button',
'sap/m/library',
"sap/base/Log"
], function(
BaseObject,
OverflowToolbarButton,
OverflowToolbarMenuButton,
OverflowToolbarToggleButton,
ToggleButton,
Button,
library,
Log
) {
"use strict";
// shortcut for sap.m.ButtonType
var ButtonType = library.ButtonType;
var OverflowToolbarAssociativePopoverControls = BaseObject.extend("sap.m._overflowToolbarHelpers.OverflowToolbarAssociativePopoverControls", {
/**
* @private
*/
constructor: function() {
this._mControlsCache = {};
},
getInterface: function() {
return this; // no facade
}
});
// Button - modifications similar to action sheet
OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMButton = function(oControl) {
var oButtonType = oControl.getType();
this._mControlsCache[oControl.getId()] = {
buttonType: oButtonType
};
if (oButtonType === ButtonType.Default) {
oControl.setProperty("type", ButtonType.Transparent, true);
}
oControl.attachEvent("_change", this._onSapMButtonUpdated, this);
};
OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMButton = function(oControl) {
var oPrevState = this._mControlsCache[oControl.getId()];
if (oControl.getType() !== oPrevState.buttonType) {
oControl.setProperty("type", oPrevState.buttonType, true);
}
oControl.detachEvent("_change", this._onSapMButtonUpdated, this);
};
OverflowToolbarAssociativePopoverControls.prototype._onSapMButtonUpdated = function(oEvent) {
var sParameterName = oEvent.getParameter("name"),
oButton = oEvent.getSource(),
sButtonId = oButton.getId();
if (typeof this._mControlsCache[sButtonId] === "undefined") {
return;
}
if (sParameterName === "type") {
this._mControlsCache[sButtonId]["buttonType"] = oButton.getType();
}
};
// OverflowToolbarButton - same as Button, but also must add the _bInOverflow trigger
OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMOverflowToolbarButton = function(oControl) {
this._preProcessSapMButton(oControl);
oControl._bInOverflow = true;
};
OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMOverflowToolbarButton = function(oControl) {
delete oControl._bInOverflow;
this._postProcessSapMButton(oControl);
};
// OverflowToolbarMenuButton - Same as button with the _bInOverflow trigger
OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMOverflowToolbarMenuButton = function(oControl) {
this._preProcessSapMButton(oControl);
oControl._bInOverflow = true;
};
OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMOverflowToolbarMenuButton = function(oControl) {
delete oControl._bInOverflow;
this._postProcessSapMButton(oControl);
};
// ToggleButton - same as button
OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMToggleButton = function(oControl) {
this._preProcessSapMButton(oControl);
};
OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMToggleButton = function(oControl) {
this._postProcessSapMButton(oControl);
};
// OverflowToolbarToggleButton - same as ToggleButton, but also must add the _bInOverflow trigger
OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMOverflowToolbarToggleButton = function(oControl) {
this._preProcessSapMToggleButton(oControl);
oControl._bInOverflow = true;
};
OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMOverflowToolbarToggleButton = function(oControl) {
delete oControl._bInOverflow;
this._postProcessSapMToggleButton(oControl);
};
/****************************** STATIC properties and methods ****************************/
/**
* A map of all controls that are commonly found in an overflow toolbar
* canOverflow - tells if the control can go to the popover or is forced to always stay in the toolbar (f.e. labels, radio buttons can never overflow)
* listenForEvents - all events that, when fired, suggest that the interaction with the control is over and the popup must be closed (f.e. button click, select change)
* noInvalidationProps - all properties of a control that, when changed, do not affect the size of the control, thus don't require a re-rendering of the toolbar (f.e. input value)
* @private
*/
OverflowToolbarAssociativePopoverControls._mSupportedControls = {
"sap.m.Button": {
canOverflow: true,
listenForEvents: ["press"],
noInvalidationProps: ["enabled", "accesskey"]
},
"sap.m.MenuButton": {
canOverflow: true,
listenForEvents: ["defaultAction", "_menuItemSelected"],
noInvalidationProps: ["enabled", "text", "icon"]
},
"sap.m.OverflowToolbarMenuButton": {
canOverflow: true,
listenForEvents: ["defaultAction", "_menuItemSelected"],
noInvalidationProps: ["enabled", "text", "icon"]
},
"sap.m.OverflowToolbarToggleButton": {
canOverflow: true,
listenForEvents: ["press"],
noInvalidationProps: ["enabled", "type", "pressed", "accesskey"]
},
"sap.m.CheckBox": {
canOverflow: true,
listenForEvents: ["select"],
noInvalidationProps: ["enabled", "selected", "accesskey"]
},
"sap.m.ToggleButton": {
canOverflow: true,
listenForEvents: ["press"],
noInvalidationProps: ["enabled", "pressed", "accesskey"]
},
"sap.m.ComboBox": {
canOverflow: true,
listenForEvents: [],
noInvalidationProps: ["enabled", "value", "selectedItemId", "selectedKey", "open"]
},
"sap.m.SearchField": {
canOverflow: true,
listenForEvents: ["search"],
noInvalidationProps: ["enabled", "value", "selectOnFocus"]
},
"sap.m.Input": {
canOverflow: true,
listenForEvents: [],
noInvalidationProps: ["enabled", "value", "accesskey"]
},
"sap.m.DateTimeInput": {
canOverflow: true,
listenForEvents: ["change"],
noInvalidationProps: ["enabled", "value", "dateValue"]
},
"sap.m.DatePicker": {
canOverflow: true,
listenForEvents: ["change"],
noInvalidationProps: ["enabled", "value", "dateValue", "displayFormat", "valueFormat", "displayFormatType", "secondaryCalendarType", "minDate", "maxDate"]
},
"sap.m.DateRangeSelection": {
canOverflow: true,
listenForEvents: ["change"],
noInvalidationProps: ["enabled", "value", "dateValue", "secondDateValue", "displayFormat", "valueFormat", "displayFormatType", "secondaryCalendarType", "minDate", "maxDate", "delimiter"]
},
"sap.m.DateTimePicker": {
canOverflow: true,
listenForEvents: ["change"],
noInvalidationProps: ["enabled", "value", "dateValue", "displayFormat", "valueFormat", "displayFormatType", "secondaryCalendarType", "minDate", "maxDate"]
},
"sap.m.TimePicker": {
canOverflow: true,
listenForEvents: ["change"],
noInvalidationProps: ["enabled", "value", "dateValue", "displayFormat", "valueFormat"]
},
"sap.m.RadioButton": {
canOverflow: false,
listenForEvents: [],
noInvalidationProps: ["enabled", "selected"]
},
"sap.m.Slider": {
canOverflow: false,
listenForEvents: [],
noInvalidationProps: ["enabled", "value"]
},
"sap.m.IconTabHeader": {
canOverflow: false,
listenForEvents: [],
noInvalidationProps: ["selectedKey"]
},
"sap.ui.comp.smartfield.SmartField": {
canOverflow: true,
listenForEvents: ["change"],
noInvalidationProps: ["enabled", "value", "valueState", "showValueHelp", "contextEditable",
"clientSideMandatoryCheck", "mandatory", "name", "placeholder", "showSuggestion", "tooltipLabel"]
},
"sap.ui.comp.smartfield.SmartLabel": {
canOverflow: true,
listenForEvents: [],
noInvalidationProps: ["enabled"]
}
};
/**
* Returns the control configuration for a given control
* @param oControl - control instance object
* @returns {*}
*/
OverflowToolbarAssociativePopoverControls.getControlConfig = function(oControl) {
var oConfig;
// First check if the control's class implements the sap.m.IOverflowToolbarContent interface
if (oControl.isA("sap.m.IOverflowToolbarContent")) {
if (typeof oControl.getOverflowToolbarConfig !== "function") {
Log.error("Required method getOverflowToolbarConfig not implemented by: " + oControl.getMetadata().getName());
return;
}
oConfig = oControl.getOverflowToolbarConfig();
if (typeof oConfig !== "object") {
Log.error("Method getOverflowToolbarConfig implemented, but does not return an object in: " + oControl.getMetadata().getName());
return;
}
return {
canOverflow: !!oConfig.canOverflow,
listenForEvents: Array.isArray(oConfig.autoCloseEvents) ? oConfig.autoCloseEvents : [],
noInvalidationProps: Array.isArray(oConfig.propsUnrelatedToSize) ? oConfig.propsUnrelatedToSize : [],
preProcess: oConfig.onBeforeEnterOverflow,
postProcess: oConfig.onAfterExitOverflow
};
}
// The interface is not implemented - check the _mSupportedControls array (legacy scenario)
var sClassName = OverflowToolbarAssociativePopoverControls.getControlClass(oControl);
oConfig = OverflowToolbarAssociativePopoverControls._mSupportedControls[sClassName];
if (oConfig === undefined) {
return;
}
var sPreProcessFnName = "_preProcess" + sClassName.split(".").map(fnCapitalize).join("");
if (typeof OverflowToolbarAssociativePopoverControls.prototype[sPreProcessFnName] === "function") {
oConfig.preProcess = OverflowToolbarAssociativePopoverControls.prototype[sPreProcessFnName];
}
var sPostProcessFnName = "_postProcess" + sClassName.split(".").map(fnCapitalize).join("");
if (typeof OverflowToolbarAssociativePopoverControls.prototype[sPostProcessFnName] === "function") {
oConfig.postProcess = OverflowToolbarAssociativePopoverControls.prototype[sPostProcessFnName];
}
return oConfig;
};
/**
* Tells if a control is supported by the associative popover (i.e. can overflow to it)
* @param oControl - control instance object
* @returns {boolean}
*/
OverflowToolbarAssociativePopoverControls.supportsControl = function(oControl) {
var oCtrlConfig = OverflowToolbarAssociativePopoverControls.getControlConfig(oControl);
return typeof oCtrlConfig !== "undefined" && oCtrlConfig.canOverflow;
};
/**
* Returns the class of a control in terms of overflow behavior
* This is needed so that for example a custom button, extending sap.m.Button, can overflow too
* @param oControl
*/
OverflowToolbarAssociativePopoverControls.getControlClass = function(oControl) {
// For now only custom classes, extending the sap.m.Button and its derivatives, are supported for overflow
if (oControl instanceof OverflowToolbarButton) {
return "sap.m.OverflowToolbarButton";
} else if (oControl instanceof OverflowToolbarMenuButton) {
return "sap.m.OverflowToolbarMenuButton";
} else if (oControl instanceof OverflowToolbarToggleButton) {
return "sap.m.OverflowToolbarToggleButton";
} else if (oControl instanceof ToggleButton) {
return "sap.m.ToggleButton";
} else if (oControl instanceof Button) {
return "sap.m.Button";
}
// All other controls must be the standard sap.m class in order to overflow
return oControl.getMetadata().getName();
};
function fnCapitalize(sName) {
return sName.substring(0, 1).toUpperCase() + sName.substr(1);
}
return OverflowToolbarAssociativePopoverControls;
});