@openui5/sap.m
Version:
OpenUI5 UI Library sap.m
1,025 lines (898 loc) • 31.2 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
sap.ui.define([
"sap/ui/core/Element",
"sap/ui/core/Lib",
'sap/ui/model/json/JSONModel',
'sap/m/VBox',
'sap/ui/core/Control',
'sap/m/Column',
'sap/m/Text',
'sap/ui/model/Filter',
"sap/m/Table",
"sap/m/OverflowToolbar",
"sap/m/SearchField",
"sap/m/ToolbarSpacer",
"sap/m/OverflowToolbarButton",
"sap/m/OverflowToolbarLayoutData",
"sap/ui/core/dnd/DragDropInfo",
'sap/ui/core/ShortcutHintsMixin',
"sap/ui/events/KeyCodes",
"sap/base/Log",
"sap/ui/Device",
"sap/m/library",
"sap/ui/core/library",
"sap/m/p13n/MessageStrip",
"sap/ui/core/InvisibleText",
"sap/m/table/Util"
], (
Element,
Library,
JSONModel,
VBox,
Control,
Column,
Text,
Filter,
Table,
OverflowToolbar,
SearchField,
ToolbarSpacer,
OverflowToolbarButton,
OverflowToolbarLayoutData,
DragDropInfo,
ShortcutHintsMixin,
KeyCodes,
Log,
Device,
library,
coreLibrary,
MessageStrip,
InvisibleText,
TableUtil
) => {
"use strict";
/**
* P13n <code>Item</code> object type.
*
* @static
* @constant
* @typedef {object} sap.m.p13n.Item
* @property {string} name The unique key of the item
* @property {string} label The label describing the personalization item
* @property {boolean} visible Defines the selection state of the personalization item
* @public
*/
/**
* Constructor for a new <code>BasePanel</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
* This control serves as base class for personalization implementations.
* This faceless class serves as a way to implement control-specific personalization panels.
*
* @extends sap.ui.core.Control
*
* @author SAP SE
* @version 1.146.0
*
* @public
* @abstract
*
* @since 1.96
* @alias sap.m.p13n.BasePanel
*/
const BasePanel = Control.extend("sap.m.p13n.BasePanel", {
metadata: {
library: "sap.m",
interfaces: [
"sap.m.p13n.IContent"
],
associations: {},
properties: {
/**
* A short text describing the panel.
* <b>Note:</b> This text will only be displayed if the panel is being used in a <code>sap.m.p13n.Popup</code>.
*/
title: {
type: "string"
},
/**
* Determines whether the reordering of personalization items is enabled.
*/
enableReorder: {
type: "boolean",
defaultValue: true
},
/**
* Determines whether the panel has a fixed width.
*
* @private
* @ui5-private sap.ui.mdc
*/
_useFixedWidth: {
type: "boolean",
defaultValue: false,
visibility: "hidden"
}
},
aggregations: {
/**
* Defines an optional message strip to be displayed in the content area.
*/
messageStrip: {
type: "sap.m.MessageStrip",
multiple: false
},
/**
* Content to be set for the <code>BasePanel</code>.
*/
_content: {
type: "sap.ui.core.Control",
multiple: false,
visibility: "hidden"
},
/**
* This template is going to be set from the implementing panel using the <code>BasePanel</code> control, by setting the template
* for the columns of the inner <code>sap.m.Table</code>.
*/
_template: {
type: "sap.ui.core.Control",
multiple: false,
visibility: "hidden"
}
},
events: {
/**
* This event is fired if any change has been made within the <code>BasePanel</code> control.
*/
change: {
parameters: {
/**
* The reason why the panel state has changed, for example, items have been added, removed, or moved.
*/
reason: {
type: "string"
},
/**
* An object containing information about the specific item that has been changed.
*/
item: {
type: "sap.m.p13n.Item"
}
}
}
}
},
renderer: {
apiVersion: 2,
render: function(oRm, oControl) {
oRm.openStart("div", oControl);
oRm.style("height", "100%");
if (oControl.getProperty("_useFixedWidth")) {
oRm.style("width", oControl.getWidth());
}
oRm.openEnd();
oRm.renderControl(oControl.getAggregation("_content"));
oRm.close("div");
}
}
});
//inner model name
BasePanel.prototype.P13N_MODEL = "$p13n";
BasePanel.prototype.LOCALIZATION_MODEL = "$p13nPanelLocalization";
//constants for change event reasoning
BasePanel.prototype.CHANGE_REASON_ADD = "Add";
BasePanel.prototype.CHANGE_REASON_REMOVE = "Remove";
BasePanel.prototype.CHANGE_REASON_MOVE = "Move";
BasePanel.prototype.CHANGE_REASON_SELECTALL = "SelectAll";
BasePanel.prototype.CHANGE_REASON_DESELECTALL = "DeselectAll";
BasePanel.prototype.CHANGE_REASON_RANGESELECT = "RangeSelect";
//defines the name of the attribute describing the presence/active state
BasePanel.prototype.PRESENCE_ATTRIBUTE = "visible";
BasePanel.prototype.WIDTH = "30rem";
BasePanel.prototype.applySettings = function(mSettings) {
Control.prototype.applySettings.apply(this, arguments);
if (!mSettings || (mSettings && mSettings.enableReorder === undefined)) {
this._updateMovement(true);
}
};
BasePanel.prototype.init = function() {
Control.prototype.init.apply(this, arguments);
this._oP13nModel = new JSONModel({});
this._oP13nModel.setSizeLimit(10000);
this.setModel(this._oP13nModel, this.P13N_MODEL);
// list is necessary to set the template + model on
this._oListControl = this._createInnerListControl();
this._oInvText = new InvisibleText({
text: this.getTitle() //use the Panel title als invisibleText title for the table
});
this._oListControl.addAriaLabelledBy(this._oInvText);
// Determines whether the rearranged item should be focused
this._bFocusOnRearrange = true;
this._setInnerLayout();
const oModel = new JSONModel({});
this.setModel(oModel, this.LOCALIZATION_MODEL);
// relevant for RangeSelect handling:
// if RangeSelect is performed using Shift+ArrowKeys
// and the focus is outside the table,
// resetting the _bShiftKeyPressed flag could not work correctly
document.addEventListener("keyup", this._keyupHandler.bind(this));
};
BasePanel.prototype.onAfterRendering = function() {
if (!this._oResizeObserver) {
this._oResizeObserver = new ResizeObserver(this._onResize.bind(this));
}
this._oResizeObserver.observe(this.getDomRef());
};
/**
* Can be overwritten if a different wrapping control is required for the inner content.
*/
BasePanel.prototype._setInnerLayout = function() {
this.setAggregation("_content", new VBox({
items: [
this._oListControl,
this._oInvText
]
}));
};
/**
* Sets the personalization state of the panel instance.
*
* @public
* @param {sap.m.p13n.Item[]} aP13nData An array containing the personalization state that is represented by the <code>BasePanel</code>.
* @returns {this} The BasePanel instance
*/
BasePanel.prototype.setP13nData = function(aP13nData) {
this._getP13nModel().setProperty("/items", aP13nData);
return this;
};
/**
* Returns the personalization state that is currently displayed by the <code>BasePanel</code>.
* @public
* @param {boolean} bOnlyActive Determines whether only the present items is included
* @returns {sap.m.p13n.Item[]} An array containing the personalization state that is currently displayed by the <code>BasePanel</code>
*/
BasePanel.prototype.getP13nData = function(bOnlyActive) {
let aItems = this._getP13nModel().getProperty("/items");
if (bOnlyActive) {
aItems = aItems.filter((oItem) => {
return oItem[this.PRESENCE_ATTRIBUTE];
});
}
return aItems;
};
/**
* Gets the corresponding <code>sap.m.p13n.Item</code> for the provided key.
*
* @public
* @param {string} sName The unique identifier
* @returns {sap.m.p13n.Item|null} The personalization model item
*/
BasePanel.prototype.getItemByKey = function(sName) {
return this.getP13nData().find((oP13nItem) => oP13nItem.name == sName);
};
/**
* Displays a <code>sap.m.MessageStrip</code> instance in the content area of the <code>BasePanel</code>.
*
* @public
* @param {sap.m.MessageStrip} oStrip Instance of a sap.m.MessageStrip
* @returns {sap.m.p13n.BasePanel} The <code>BasePanel</code> instance
*/
BasePanel.prototype.setMessageStrip = function(oStrip) {
if (!oStrip) {
this.getAggregation("_content").removeItem(this._oMessageStrip);
this._oMessageStrip = null;
} else {
oStrip.addStyleClass("sapUiSmallMargin");
if (this._oMessageStrip) {
this._oMessageStrip.destroy();
}
this._oMessageStrip = oStrip;
this.getAggregation("_content").insertItem(oStrip, 0);
}
return this;
};
/**
* Getter for the <code>messageStrip</code> aggregation.
*
* @public
* @returns {sap.m.p13n.BasePanel} The BasePanel instance
*/
BasePanel.prototype.getMessageStrip = function() {
return this._oMessageStrip;
};
/**
* Getter for the fixed panel width
*
* @private
* @ui5-restricted sap.ui.mdc
* @returns {string} The fixed panel width
*/
BasePanel.prototype.getWidth = function() {
return this.WIDTH;
};
/**
* @param {boolean} bEnableReorder Determines whether reordering is enabled
* @private
* @returns {sap.m.p13n.BasePanel} The BasePanel instance
*/
BasePanel.prototype._updateMovement = function(bEnableReorder) {
const oTemplate = this.getAggregation("_template");
if (bEnableReorder) {
this._addHover(oTemplate);
} else if (oTemplate && oTemplate.aDelegates && oTemplate.aDelegates.length > 0) {
oTemplate.removeEventDelegate(oTemplate.aDelegates[0].oDelegate);
}
this._getDragDropConfig().setEnabled(bEnableReorder);
this._setMoveButtonVisibility(bEnableReorder);
return this;
};
/**
* The <code>enableReorder</code> property determines whether additional move buttons are shown when hovering over
* the inner list. In addition, drag and drop will be enabled for the inner list control.
*
* @param {boolean} bEnableReorder Determines whether reordering is enabled
* @public
* @returns {sap.m.p13n.BasePanel} The BasePanel instance
*/
BasePanel.prototype.setEnableReorder = function(bEnableReorder) {
this.setProperty("enableReorder", bEnableReorder);
this._updateMovement(bEnableReorder);
return this;
};
/**
* Trigger to update the panel after outer influences (e.g. sap.m.p13n.Popup) trigger a reset on the panel
*
* @private
* @ui5-restricted
*/
BasePanel.prototype.onReset = function() {
this._getSearchField()?.setValue(""); //Reset the searchfield string
this._oListControl.getBinding("items")?.filter([]); //Reset the filtering
};
BasePanel.prototype._getDragDropConfig = function() {
if (!this._oDragDropInfo) {
this._oDragDropInfo = new DragDropInfo({
enabled: false,
sourceAggregation: "items",
targetAggregation: "items",
dropPosition: "Between",
drop: [this._onRearrange, this]
});
}
return this._oDragDropInfo;
};
BasePanel.prototype._getMoveTopButton = function() {
if (!this._oMoveTopButton) {
this._oMoveTopButton = new OverflowToolbarButton(this.getId() + "-moveTopBtn", {
type: "Transparent",
tooltip: this._getResourceText("p13n.MOVE_TO_TOP"),
icon: "sap-icon://collapse-group",
press: [this._onPressButtonMoveToTop, this],
visible: false
});
this.addDependent(this._oMoveTopButton);
ShortcutHintsMixin.addConfig(this._oMoveTopButton, {
addAccessibilityLabel: true,
message: this._getResourceText(Device.os.macintosh ? "p13n.SHORTCUT_MOVE_TO_TOP_MAC" : "p13n.SHORTCUT_MOVE_TO_TOP") // Cmd+Home or Ctrl+Home
}, this
);
}
return this._oMoveTopButton;
};
BasePanel.prototype._getMoveUpButton = function() {
if (!this._oMoveUpButton) {
this._oMoveUpButton = new OverflowToolbarButton(this.getId() + "-moveUpBtn", {
type: "Transparent",
tooltip: this._getResourceText("p13n.MOVE_UP"),
icon: "sap-icon://navigation-up-arrow",
press: [this._onPressButtonMoveUp, this],
visible: false
});
this.addDependent(this._oMoveUpButton);
ShortcutHintsMixin.addConfig(this._oMoveUpButton, {
addAccessibilityLabel: true,
message: this._getResourceText(Device.os.macintosh ? "p13n.SHORTCUT_MOVE_UP_MAC" : "p13n.SHORTCUT_MOVE_UP") // Cmd+CursorUp or Ctrl+CursorUp
}, this
);
}
return this._oMoveUpButton;
};
BasePanel.prototype._getMoveDownButton = function() {
if (!this._oMoveDownButton) {
this._oMoveDownButton = new OverflowToolbarButton(this.getId() + "-moveDownpBtn", {
type: "Transparent",
tooltip: this._getResourceText("p13n.MOVE_DOWN"),
icon: "sap-icon://navigation-down-arrow",
press: [this._onPressButtonMoveDown, this],
visible: false
});
this.addDependent(this._oMoveDownButton);
ShortcutHintsMixin.addConfig(this._oMoveDownButton, {
addAccessibilityLabel: true,
message: this._getResourceText(Device.os.macintosh ? "p13n.SHORTCUT_MOVE_DOWN_MAC" : "p13n.SHORTCUT_MOVE_DOWN") // Cmd+CursorDown or Ctrl+CursorDown
}, this
);
}
return this._oMoveDownButton;
};
BasePanel.prototype._getMoveBottomButton = function() {
if (!this._oMoveBottomButton) {
this._oMoveBottomButton = new OverflowToolbarButton(this.getId() + "-moveBottomBtn", {
type: "Transparent",
tooltip: this._getResourceText("p13n.MOVE_TO_BOTTOM"),
icon: "sap-icon://expand-group",
press: [this._onPressButtonMoveToBottom, this],
visible: false
});
this.addDependent(this._oMoveBottomButton);
ShortcutHintsMixin.addConfig(this._oMoveBottomButton, {
addAccessibilityLabel: true,
message: this._getResourceText(Device.os.macintosh ? "p13n.SHORTCUT_MOVE_TO_BOTTOM_MAC" : "p13n.SHORTCUT_MOVE_TO_BOTTOM") // Cmd+End or Ctrl+End
}, this
);
}
return this._oMoveBottomButton;
};
BasePanel.prototype._onResize = function(aResizeEntity) {
const oDomRect = aResizeEntity[0].contentRect;
if (this._oMoveTopButton) {
this._oMoveTopButton.setVisible(oDomRect.width > 400);
}
if (this._oMoveBottomButton) {
this._oMoveBottomButton.setVisible(oDomRect.width > 400);
}
};
BasePanel.prototype._createInnerListControl = function() {
return new Table(this.getId() + "-innerP13nList", Object.assign(this._getListControlConfig(), {
headerToolbar: new OverflowToolbar({
content: [
this._getSearchField(),
new ToolbarSpacer(),
this._getMoveTopButton(),
this._getMoveUpButton(),
this._getMoveDownButton(),
this._getMoveBottomButton()
]
})
}));
};
BasePanel.prototype._addHover = function(oRow) {
if (oRow && oRow.aDelegates.length < 1) {
oRow.addEventDelegate({
onmouseover: this._hoverHandler.bind(this),
onfocusin: this._focusHandler.bind(this),
onkeydown: this._keydownHandler.bind(this),
onkeyup: this._keyupHandler.bind(this)
});
}
};
BasePanel.prototype._keyupHandler = function(oEvent) {
if (oEvent.key === "Shift") {
this._bShiftKeyPressed = false;
}
};
BasePanel.prototype._keydownHandler = function(oEvent) {
if (!this.getEnableReorder()) {
return;
}
if (oEvent.isMarked()) {
return;
}
// Log.info("onKeyDown", oEvent.ctrlKey + " | " + oEvent.which + " | " + oEvent.key);
if (oEvent.key === "Shift" || oEvent.shiftKey) {
this._bShiftKeyPressed = true;
}
if ((oEvent.metaKey || oEvent.ctrlKey)) {
let oButton;
if (oEvent.which === KeyCodes.HOME) {
oButton = this._getMoveTopButton();
}
if (oEvent.which === KeyCodes.ARROW_UP) {
oButton = this._getMoveUpButton();
}
if (oEvent.which === KeyCodes.ARROW_DOWN) {
oButton = this._getMoveDownButton();
}
if (oEvent.which === KeyCodes.END) {
oButton = this._getMoveBottomButton();
}
if (oButton && oButton.getParent() && oButton.getVisible() && oButton.getEnabled()) {
// Mark the event to ensure that parent handlers (e.g. FLP) can skip their processing if needed. Also prevent potential browser defaults
oEvent.setMarked();
oEvent.preventDefault();
oEvent.stopPropagation();
oButton.firePress();
}
}
};
BasePanel.prototype._focusHandler = function(oEvt) {
if (!this.getEnableReorder()) {
return;
}
//(new) hovered item
const oHoveredItem = Element.getElementById(oEvt.currentTarget.id);
this._handleActivated(oHoveredItem);
};
BasePanel.prototype._hoverHandler = function(oEvt) {
//Only use hover if no item has been selected yet
if (this._oSelectedItem && !this._oSelectedItem.bIsDestroyed) {
return;
}
if (!this.getEnableReorder()) {
return;
}
//(new) hovered item
const oHoveredItem = Element.getElementById(oEvt.currentTarget.id);
this._handleActivated(oHoveredItem);
};
BasePanel.prototype._handleActivated = function(oHoveredItem) {
this._oHoveredItem = oHoveredItem;
//Implement custom hover handling in derivation here..
};
BasePanel.prototype._getListControlConfig = function() {
return {
mode: "MultiSelect",
rememberSelections: true,
itemPress: [this._onItemPressed, this],
selectionChange: [this._onSelectionChange, this],
sticky: ["HeaderToolbar", "ColumnHeaders", "InfoToolbar"],
dragDropConfig: this._getDragDropConfig()
};
};
BasePanel.prototype._getSearchField = function() {
if (!this._oSearchField) {
this._oSearchField = new SearchField(this.getId() + "-searchField", {
liveChange: [this._onSearchFieldLiveChange, this],
width: "100%",
layoutData: new OverflowToolbarLayoutData({
shrinkable: true,
priority: "High",
maxWidth: "16rem"
}),
change: [this._announceSearchUpdate, this]
});
}
return this._oSearchField;
};
BasePanel.prototype._announceSearchUpdate = function() {
TableUtil.announceTableUpdate(this.getTableInvisibleText().getText(), this._oListControl.getItems().length);
};
/**
* Getter for the initial focusable <code>control</code> on the panel.
*
* @returns {sap.ui.core.Control} Control instance which could get the focus.
*
* @private
* @ui5-restricted sap.m, sap.ui.mdc
*/
BasePanel.prototype.getInitialFocusedControl = function() {
return this._oSearchField;
};
/**
* @private
* @ui5-restricted sap.m.p13n
* Returns the <code>InvisibleText</code> control describing the table in the personalization panel.
*
* @returns {sap.ui.core.InvisibleText} The invisible text describing the table control.
*/
BasePanel.prototype.getTableInvisibleText = function() {
return this._oInvText;
};
BasePanel.prototype.setTitle = function(sTitle) {
this.setProperty("title", sTitle);
this._oInvText?.setText(sTitle);
return this;
};
BasePanel.prototype._setTemplate = function(oTemplate) {
oTemplate.setType("Active");
const oCurrentTemplate = this.getAggregation("_template");
if (oCurrentTemplate) {
oCurrentTemplate.destroy();
}
this.setAggregation("_template", oTemplate);
if (oTemplate) {
if (this.getEnableReorder()) {
this._addHover(oTemplate);
}
this._oSelectionBindingInfo = oTemplate.getBindingInfo("selected");
// Extract the binding info parts
if (this._oSelectionBindingInfo && this._oSelectionBindingInfo.parts) {
this._oSelectionBindingInfo = {
parts: this._oSelectionBindingInfo.parts
};
}
}
this._bindListItems();
return this;
};
BasePanel.prototype._setPanelColumns = function(vColumns) {
let aColumns;
if (vColumns instanceof Array) {
aColumns = vColumns;
} else {
aColumns = [
vColumns
];
}
this._addTableColumns(aColumns);
};
BasePanel.prototype._getP13nModel = function() {
return this.getModel(this.P13N_MODEL);
};
BasePanel.prototype._getResourceText = function(sText, aValue) {
this.oResourceBundle = this.oResourceBundle ? this.oResourceBundle : Library.getResourceBundleFor("sap.m");
return sText ? this.oResourceBundle.getText(sText, aValue) : this.oResourceBundle;
};
BasePanel.prototype._addTableColumns = function(aColumns) {
const aRemovedColumns = this._oListControl.removeAllColumns();
aRemovedColumns.forEach((oRemovedColumn) => {
oRemovedColumn.destroy();
});
aColumns.forEach(function(vColumn) {
let oColumn;
if (typeof vColumn == "string") {
oColumn = new Column({
header: new Text({
text: vColumn
})
});
} else {
oColumn = vColumn;
}
this._oListControl.addColumn(oColumn);
}, this);
};
BasePanel.prototype._bindListItems = function(mBindingInfo) {
const oTemplate = this.getAggregation("_template");
if (oTemplate) {
this._oListControl.bindItems(Object.assign({
path: this.P13N_MODEL + ">/items",
key: "name",
templateShareable: false,
template: this.getAggregation("_template").clone()
}, mBindingInfo));
}
};
/**
* Evaluates a given filter recursively including its subfilters against a given item.
* @param {sap.ui.model.Filter} oFilter Filter to evaluate
* @param {object} oItem p13n item to evaluate the filter against
* @returns {boolean} Whether the filter matched the item
*/
function evaluateFilter(oFilter, oItem) {
const aSubFilters = oFilter.getFilters && oFilter.getFilters();
if (aSubFilters && aSubFilters.length > 0) {
if (oFilter.bAnd) {
return aSubFilters.every((oSubFilter) => evaluateFilter(oSubFilter, oItem));
} else {
return aSubFilters.some((oSubFilter) => evaluateFilter(oSubFilter, oItem));
}
} else {
let sValue = oItem[oFilter.getPath()];
if (typeof sValue === "string") {
sValue = sValue.toUpperCase();
}
// If a Filter is build like this, "new Filter([], true)" it won't have a test function. As fallback, true should be returned, as an "empty" filter matches everything.
return oFilter.getTest()?.(sValue) ?? true;
}
}
BasePanel.prototype._onSelectionChange = function(oEvent) {
const oSelectedItem = oEvent.getParameter("listItem");
this._oLastSelectedItem = oSelectedItem;
const aListItems = oEvent.getParameter("listItems");
let sSpecialChangeReason = this._checkSpecialChangeReason(oEvent.getParameter("selectAll"), oEvent.getParameter("listItems"));
if (sSpecialChangeReason) {
let aModelItems = [];
if (sSpecialChangeReason === this.CHANGE_REASON_DESELECTALL || sSpecialChangeReason === this.CHANGE_REASON_SELECTALL) {
const aFilters = this._oListControl.getBinding("items").getFilters("Control");
aModelItems = this.getP13nData();
if (aFilters.length > 0) {
aModelItems = aModelItems.filter((oItem) => {
return aFilters.reduce((bResult, oFilter) => {
return bResult || evaluateFilter(oFilter, oItem);
}, false);
});
}
aModelItems = aModelItems.map((oItem) => {
oItem[this.PRESENCE_ATTRIBUTE] = sSpecialChangeReason === this.CHANGE_REASON_SELECTALL;
return oItem;
});
if (aModelItems.length !== this.getP13nData().length) {
// This case will happen, if the user filtered the list and then selects/deselects all items. This should then be treated as RangeSelect instead of SelectAll/DeselectAll
sSpecialChangeReason = this.CHANGE_REASON_RANGESELECT;
}
} else {
aModelItems = aListItems.map((oTableItem) => this._getModelEntry(oTableItem));
}
this.fireChange({
reason: sSpecialChangeReason,
item: aModelItems
});
} else {
aListItems.forEach(function(oTableItem) {
this._selectTableItem(oTableItem, !!sSpecialChangeReason);
}, this);
}
// in case of 'deselect all', the move buttons for positioning are going to be disabled
if (sSpecialChangeReason === this.CHANGE_REASON_DESELECTALL) {
this._getMoveTopButton().setEnabled(false);
this._getMoveUpButton().setEnabled(false);
this._getMoveDownButton().setEnabled(false);
this._getMoveBottomButton().setEnabled(false);
}
if (this.getEnableReorder() && oSelectedItem?.isDestroyed() == false) {
this._handleActivated(oSelectedItem);
}
};
BasePanel.prototype._checkSpecialChangeReason = function(bSelectAll, aListItems) {
let sSpecialChangeReason;
if (bSelectAll) {
sSpecialChangeReason = this.CHANGE_REASON_SELECTALL;
} else if (!bSelectAll && aListItems.length > 1 && !aListItems[0].getSelected()) {
sSpecialChangeReason = this.CHANGE_REASON_DESELECTALL;
} else if (aListItems.length < this._oListControl.getItems().length && (aListItems.length > 1 || (aListItems.length >= 1 && (this._bShiftKeyPressed ?? false)))) {
sSpecialChangeReason = this.CHANGE_REASON_RANGESELECT;
}
return sSpecialChangeReason;
};
BasePanel.prototype._onItemPressed = function(oEvent) {
const oTableItem = oEvent.getParameter('listItem');
this._oSelectedItem = oTableItem;
const oContext = oTableItem.getBindingContext(this.P13N_MODEL);
if (this.getEnableReorder() && oContext && oContext.getProperty(this.PRESENCE_ATTRIBUTE)) {
this._handleActivated(oTableItem);
this._updateEnableOfMoveButtons(oTableItem, true);
}
};
BasePanel.prototype._onSearchFieldLiveChange = function(oEvent) {
this._oListControl.getBinding("items").filter(new Filter("label", "Contains", oEvent.getSource().getValue()));
};
BasePanel.prototype._onPressButtonMoveToTop = function() {
this._moveSelectedItem(0);
};
BasePanel.prototype._onPressButtonMoveUp = function() {
this._moveSelectedItem("Up");
};
BasePanel.prototype._onPressButtonMoveDown = function() {
this._moveSelectedItem("Down");
};
BasePanel.prototype._onPressButtonMoveToBottom = function() {
const iIndex = this._oListControl.getItems().length - 1;
this._moveSelectedItem(iIndex);
};
BasePanel.prototype._setMoveButtonVisibility = function(bVisible) {
this._getMoveTopButton().setVisible(bVisible);
this._getMoveUpButton().setVisible(bVisible);
this._getMoveDownButton().setVisible(bVisible);
this._getMoveBottomButton().setVisible(bVisible);
};
BasePanel.prototype._filterBySelected = function(bShowSelected, oList) {
oList.getBinding("items").filter(bShowSelected ? new Filter(this.PRESENCE_ATTRIBUTE, "EQ", true) : []);
};
BasePanel.prototype._selectTableItem = function(oTableItem, bSpecialChangeReason) {
this._updateEnableOfMoveButtons(oTableItem, bSpecialChangeReason ? false : true);
this._oSelectedItem = oTableItem;
if (!bSpecialChangeReason) {
const oItem = this._getP13nModel().getProperty(this._oSelectedItem.getBindingContext(this.P13N_MODEL).sPath);
this.fireChange({
reason: oItem[this.PRESENCE_ATTRIBUTE] ? this.CHANGE_REASON_ADD : this.CHANGE_REASON_REMOVE,
item: oItem
});
}
};
BasePanel.prototype._moveSelectedItem = function(vNewIndex) {
const oSelectedItem = this._oSelectedItem;
const iSelectedIndex = this._oListControl.indexOfItem(oSelectedItem);
if (iSelectedIndex < 0) {
return;
}
// determine the new index relative to selected index when "Up" or "Down" is passed as a parameter
const iNewIndex = (typeof vNewIndex == "number") ? vNewIndex : iSelectedIndex + (vNewIndex == "Up" ? -1 : 1);
this._moveTableItem(oSelectedItem, iNewIndex);
};
BasePanel.prototype._getModelEntry = function(oItem) {
return oItem.getBindingContext(this.P13N_MODEL).getObject();
};
BasePanel.prototype._moveTableItem = function(oItem, iNewIndex) {
const aItems = this._oListControl.getItems();
const aModelItems = this._getP13nModel().getProperty("/items");
// index of the item in the model not the index in the aggregation
const iOldModelIndex = aModelItems.indexOf(this._getModelEntry(oItem));
// limit the minumum and maximum index
let iNewModelIndex = (iNewIndex <= 0) ? 0 : Math.min(iNewIndex, aItems.length - 1);
// new index of the item in the model
iNewModelIndex = aModelItems.indexOf(this._getModelEntry(aItems[iNewIndex]));
if (iNewModelIndex == iOldModelIndex) {
return;
}
// remove data from old position and insert it into new position
aModelItems.splice(iNewModelIndex, 0, aModelItems.splice(iOldModelIndex, 1)[0]);
this._getP13nModel().setProperty("/items", aModelItems);
// store the moved item again due to binding
this._oSelectedItem = this._oListControl.getItems()[iNewIndex];
this._updateEnableOfMoveButtons(this._oSelectedItem, this._bFocusOnRearrange);
this._handleActivated(this._oSelectedItem);
this.fireChange({
reason: this.CHANGE_REASON_MOVE,
item: this._getModelEntry(oItem)
});
};
BasePanel.prototype._onRearrange = function(oEvent) {
const oDraggedItem = oEvent.getParameter("draggedControl");
const oModelEntry = this._getModelEntry(oDraggedItem);
// SNOW DINC0418886: dedicated check, if a disabled checkbox exists. If a checkbox exists, or it is enabled, skip this check
if (oDraggedItem?.getMultiSelectControl() && !oDraggedItem.getMultiSelectControl().getEnabled() && oModelEntry.enabled !== "visibility") {
return;
}
const oDroppedItem = oEvent.getParameter("droppedControl");
const sDropPosition = oEvent.getParameter("dropPosition");
const iDraggedIndex = this._oListControl.indexOfItem(oDraggedItem);
const iDroppedIndex = this._oListControl.indexOfItem(oDroppedItem);
const iActualDroppedIndex = iDroppedIndex + (sDropPosition == "Before" ? 0 : 1) + (iDraggedIndex < iDroppedIndex ? -1 : 0);
this._moveTableItem(oDraggedItem, iActualDroppedIndex);
};
BasePanel.prototype._updateEnableOfMoveButtons = function(oTableItem, bFocus) {
const iTableItemPos = this._oListControl.getItems().indexOf(oTableItem);
let bUpEnabled = true,
bDownEnabled = true;
if (iTableItemPos == 0) {
// disable move buttons upwards, if the item is at the top
bUpEnabled = false;
}
if (iTableItemPos == this._oListControl.getItems().length - 1) {
// disable move buttons downwards, if the item is at the bottom
bDownEnabled = false;
}
this._getMoveTopButton().setEnabled(bUpEnabled);
this._getMoveUpButton().setEnabled(bUpEnabled);
this._getMoveDownButton().setEnabled(bDownEnabled);
this._getMoveBottomButton().setEnabled(bDownEnabled);
if (bFocus) {
oTableItem.focus();
}
};
/**
* @deprecated As of version 1.120
*/
BasePanel.prototype.onlocalizationChanged = function() {
this._onLocalizationChanged();
};
/**
* Localization changed
* @private
*/
BasePanel.prototype.onLocalizationChanged = function() {
this._onLocalizationChanged();
};
BasePanel.prototype._onLocalizationChanged = function() {
this.oResourceBundle = Library.getResourceBundleFor("sap.m");
if (this._updateLocalizationTexts && typeof this._updateLocalizationTexts === "function") {
this._updateLocalizationTexts();
}
this.invalidate();
};
BasePanel.prototype.exit = function() {
Control.prototype.exit.apply(this, arguments);
this._oResizeObserver = null;
this._bFocusOnRearrange = null;
this._oHoveredItem = null;
this._oSelectionBindingInfo = null;
this._oSelectedItem = null;
this._oLastSelectedItem = null;
this._oListControl = null;
this._oMoveTopButton = null;
this._oMoveUpButton = null;
this._oMoveDownButton = null;
this._oMoveBottomButton = null;
this._oSearchField = null;
document.removeEventListener("keyup", this._keyupHandler.bind(this));
};
return BasePanel;
});