UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

620 lines (542 loc) 18.9 kB
/*! * 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.P13nSelectionPanel. sap.ui.define([ './library', './ColumnListItem', './P13nPanel', './SearchField', './Text', './Table', './Column', './ScrollContainer', './P13nSelectionItem', './VBox', './Link', './OverflowToolbar', './OverflowToolbarLayoutData', './ToolbarSpacer', 'sap/ui/core/library', 'sap/ui/model/ChangeReason', 'sap/ui/model/json/JSONModel', 'sap/ui/model/BindingMode', 'sap/ui/core/ResizeHandler', "sap/ui/thirdparty/jquery" ], function(library, ColumnListItem, P13nPanel, SearchField, Text, Table, Column, ScrollContainer, P13nSelectionItem /* kept for compatibility*/, VBox, Link, OverflowToolbar, OverflowToolbarLayoutData, ToolbarSpacer, CoreLibrary, ChangeReason, JSONModel, BindingMode, ResizeHandler, jQuery) { "use strict"; // shortcut for sap.m.ToolbarDesign var ToolbarDesign = library.ToolbarDesign; // shortcut for sap.m.ListType var ListType = library.ListType; // shortcut for sap.m.ListMode var ListMode = library.ListMode; // shortcut for sap.m.P13nPanelType var P13nPanelType = library.P13nPanelType; // shortcut for sap.ui.core.VerticalAlign var OverflowToolbarPriority = library.OverflowToolbarPriority; /** * Constructor for a new P13nSelectionPanel. * * @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 The P13nSelectionPanel control is used to define selection settings like the visibility or the order of items. * @extends sap.m.P13nPanel * @author SAP SE * @version 1.117.4 * @constructor * @private * @since 1.46.0 * @alias sap.m.P13nSelectionPanel */ var P13nSelectionPanel = P13nPanel.extend("sap.m.P13nSelectionPanel", /** @lends sap.m.P13nSelectionPanel.prototype */ { metadata: { library: "sap.m", aggregations: { /** * List of columns that has been changed */ selectionItems: { type: "sap.m.P13nSelectionItem", multiple: true, singularName: "selectionItem", bindable: "bindable" }, /** * Internal aggregation for the toolbar */ content: { type: "sap.ui.core.Control", multiple: true, singularName: "content", visibility: "hidden" } }, events: { /** * Event raised if <code>selectionItems</code> is changed or new one needs to be created in the model. * * @since 1.52 */ changeSelectionItems: { parameters: { /** * Array contains an object for each item in <code>items</code> aggregation enriched with * visibility information. The item order reflects the current order of columns in the panel. * @since 1.52 */ items: { type: "object[]" } } } } }, renderer: { apiVersion: 2, render: function(oRm, oControl){ oRm.openStart("div", oControl); oRm.class("sapMP13nColumnsPanel"); oRm.openEnd(); oControl.getAggregation("content").forEach(function(oChildren){ oRm.renderControl(oChildren); }); oRm.close("div"); } } }); // ----------------------- Overwrite Method ----------------- P13nSelectionPanel.prototype.init = function() { this._iLiveChangeTimer = 0; this._iSearchTimer = 0; this._bIgnoreUpdateInternalModel = false; this._bUpdateInternalModel = true; this._bOnAfterRenderingFirstTimeExecuted = false; var oModel = new JSONModel({ items: [], countOfSelectedItems: 0, countOfItems: 0 }); oModel.setDefaultBindingMode(BindingMode.TwoWay); oModel.setSizeLimit(1000); this.setModel(oModel, "$sapmP13nSelectionPanel"); this.setType(P13nPanelType.selection); this._createTable(); this._createToolbar(); this.setVerticalScrolling(false); var oScrollContainer = new ScrollContainer({ horizontal: false, vertical: true, content: [ this._oTable ], width: '100%', height: '100%' }); this.addAggregation("content", oScrollContainer); // Call-back for handling of resizing // TODO: make sure we optimize calculation and respect margins and borders, use e.g. // jQuery.outerHeight(true) var that = this; this._fnHandleResize = function() { var bChangeResult = false, iScrollContainerHeightOld, iScrollContainerHeightNew; if (that.getParent) { var $dialogCont = null, iContentHeight, iHeaderHeight; var oParent = that.getParent(); var oToolbar = that._getToolbar(); if (oParent && oParent.$) { $dialogCont = oParent.$("cont"); if ($dialogCont.children().length > 0 && oToolbar.$().length > 0) { iScrollContainerHeightOld = oScrollContainer.$()[0].clientHeight; iContentHeight = $dialogCont.children()[0].clientHeight; iHeaderHeight = oToolbar ? oToolbar.$()[0].clientHeight : 0; iScrollContainerHeightNew = iContentHeight - iHeaderHeight; if (iScrollContainerHeightOld !== iScrollContainerHeightNew) { oScrollContainer.setHeight(iScrollContainerHeightNew + 'px'); bChangeResult = true; } } } } return bChangeResult; }; this._sContainerResizeListener = ResizeHandler.register(oScrollContainer, this._fnHandleResize); }; P13nSelectionPanel.prototype.onBeforeRendering = function() { this._updateInternalModel(); }; P13nSelectionPanel.prototype.onAfterRendering = function() { var that = this; // adapt scroll-container very first time to the right size of the browser if (!this._bOnAfterRenderingFirstTimeExecuted) { this._bOnAfterRenderingFirstTimeExecuted = true; window.clearTimeout(this._iLiveChangeTimer); this._iLiveChangeTimer = window.setTimeout(function() { that._fnHandleResize(); }, 0); } }; P13nSelectionPanel.prototype.getOkPayload = function() { this._updateInternalModel(); var aMItems = this._getInternalModel().getProperty("/items"); return { // We have to return selectionItems as of the fact that new created or deleted selectionItems // are not updated in the model via list binding. selectionItems: aMItems.map(function(oMItem) { return { columnKey: oMItem.columnKey, selected: oMItem.persistentSelected }; }) }; }; P13nSelectionPanel.prototype.exit = function() { ResizeHandler.deregister(this._sContainerResizeListener); this._sContainerResizeListener = null; this._getToolbar().destroy(); this._oTable.destroy(); this._oTable = null; // destroy model and its data if (this._getInternalModel()) { this._getInternalModel().destroy(); } window.clearTimeout(this._iLiveChangeTimer); window.clearTimeout(this._iSearchTimer); }; // ----------------------- Overwrite Methods of Item Aggregation ---------------------- P13nSelectionPanel.prototype.addItem = function(oItem) { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } this.addAggregation("items", oItem); return this; }; P13nSelectionPanel.prototype.insertItem = function(oItem, iIndex) { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } this.insertAggregation("items", oItem, iIndex); return this; }; P13nSelectionPanel.prototype.removeItem = function(oItem) { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } oItem = this.removeAggregation("items", oItem); return oItem; }; P13nSelectionPanel.prototype.removeAllItems = function() { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } return this.removeAllAggregation("items"); }; P13nSelectionPanel.prototype.destroyItems = function() { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } this.destroyAggregation("items"); return this; }; // ----------------------- Overwrite Methods of SelectionItem Aggregation --------------------- P13nSelectionPanel.prototype.addSelectionItem = function(oSelectionItem) { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } this.addAggregation("selectionItems", oSelectionItem); return this; }; P13nSelectionPanel.prototype.insertSelectionItem = function(oSelectionItem, iIndex) { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } this.insertAggregation("selectionItems", oSelectionItem, iIndex); return this; }; P13nSelectionPanel.prototype.updateSelectionItems = function(sReason) { this.updateAggregation("selectionItems"); if (sReason === ChangeReason.Change && !this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } }; P13nSelectionPanel.prototype.removeSelectionItem = function(oSelectionItem) { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } return this.removeAggregation("selectionItems", oSelectionItem); }; P13nSelectionPanel.prototype.removeAllSelectionItems = function() { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } return this.removeAllAggregation("selectionItems"); }; P13nSelectionPanel.prototype.destroySelectionItems = function() { if (!this._bIgnoreUpdateInternalModel) { this._bUpdateInternalModel = true; } this.destroyAggregation("selectionItems"); return this; }; // ----------------------- Overwrite Method of P13nPanel ----------------- P13nSelectionPanel.prototype.onBeforeNavigationFrom = function() { // this._syncModel2Panel(); return true; }; P13nSelectionPanel.prototype._notifyChange = function() { var fListener = this.getChangeNotifier(); if (fListener) { fListener(this); } }; // -------------------------- new -------------------------------------------- P13nSelectionPanel.prototype._getInternalModel = function() { return this.getModel("$sapmP13nSelectionPanel"); }; P13nSelectionPanel.prototype._createTable = function() { var that = this; this._oTable = new Table({ mode: ListMode.MultiSelect, rememberSelections: false, selectionChange: jQuery.proxy(this._onSelectionChange, this), columns: [ new Column({ vAlign: CoreLibrary.VerticalAlign.Middle, header: new Text({ text: { parts: [ { path: '/countOfSelectedItems' }, { path: '/countOfItems' } ], formatter: function(iCountOfSelectedItems, iCountOfItems) { return sap.ui.getCore().getLibraryResourceBundle("sap.m").getText('COLUMNSPANEL_SELECT_ALL_WITH_COUNTER', [ iCountOfSelectedItems, iCountOfItems ]); } } }) }) ], items: { path: "/items", templateShareable: false, template: new ColumnListItem({ cells: new VBox({ items: [ new Link({ href: "{href}", text: "{text}", target: "{target}", wrapping: true, enabled: { path: 'href', formatter: function(oValue) { if (!oValue) { this.addStyleClass("sapUiCompSmartLink"); } return !!oValue; } }, press: function(oEvent) { var sHref = oEvent.getSource().getHref(); var oItems = that.getItems().filter(function(oItem) { return oItem.getHref() === sHref && !!oItem.getPress(); }); if (!oItems.length) { return; } var fnPress = oItems[0].getPress(); fnPress(oEvent); } }), new Text({ wrapping: true, visible: { path: 'description', formatter: function(sDescription) { return !!sDescription; } }, text: "{description}" }) ] }), visible: "{visible}", selected: "{persistentSelected}", tooltip: "{tooltip}", type: ListType.Active }) } }); this._oTable.setModel(this._getInternalModel()); }; P13nSelectionPanel.prototype._createToolbar = function() { var that = this; var oToolbar = new OverflowToolbar(this.getId() + "-toolbar", { design: ToolbarDesign.Auto, content: [ new ToolbarSpacer(), new SearchField(this.getId() + "-searchField", { liveChange: function(oEvent) { var sValue = oEvent.getSource().getValue(), iDelay = (sValue ? 300 : 0); // no delay if value is empty // execute search after user stops typing for 300ms window.clearTimeout(that._iSearchTimer); if (iDelay) { that._iSearchTimer = window.setTimeout(function() { that._onExecuteSearch(); }, iDelay); } else { that._onExecuteSearch(); } }, // execute the standard search search: jQuery.proxy(this._onExecuteSearch, this), layoutData: new OverflowToolbarLayoutData({ minWidth: "12.5rem", maxWidth: "23.077rem", shrinkable: true, priority: OverflowToolbarPriority.NeverOverflow // priority: OverflowToolbarPriority.High }) }) ] }); oToolbar.setModel(this._getInternalModel()); this.addAggregation("content", oToolbar); }; P13nSelectionPanel.prototype._onExecuteSearch = function() { this._switchVisibilityOfUnselectedModelItems(); this._filterModelItemsBySearchText(); this._updateControlLogic(); }; P13nSelectionPanel.prototype._switchVisibilityOfUnselectedModelItems = function() { var bShowOnlySelectedItems = this._isFilteredByShowSelected(); var aMItems = this._getInternalModel().getProperty("/items"); aMItems.forEach(function(oMItem) { if (oMItem.persistentSelected) { oMItem.visible = true; return; } oMItem.visible = !bShowOnlySelectedItems; }); this._getInternalModel().setProperty("/items", aMItems); }; P13nSelectionPanel.prototype._getVisibleModelItems = function() { return this._getInternalModel().getProperty("/items").filter(function(oMItem) { return !!oMItem.visible; }); }; P13nSelectionPanel.prototype._getModelItemByColumnKey = function(sColumnKey) { var aMItems = this._getInternalModel().getProperty("/items").filter(function(oMItem) { return oMItem.columnKey === sColumnKey; }); return aMItems[0]; }; P13nSelectionPanel.prototype._updateCounts = function(aMItems) { var iCountOfItems = 0; var iCountOfSelectedItems = 0; aMItems.forEach(function(oMItem) { iCountOfItems++; if (oMItem.persistentSelected) { iCountOfSelectedItems++; } }); this._getInternalModel().setProperty("/countOfItems", iCountOfItems); this._getInternalModel().setProperty("/countOfSelectedItems", iCountOfSelectedItems); }; P13nSelectionPanel.prototype._getToolbar = function() { return sap.ui.getCore().byId(this.getId() + "-toolbar") || null; }; P13nSelectionPanel.prototype._getSearchField = function() { return sap.ui.getCore().byId(this.getId() + "-searchField") || null; }; P13nSelectionPanel.prototype._getSearchText = function() { var oSearchField = this._getSearchField(); return oSearchField ? oSearchField.getValue() : ""; }; P13nSelectionPanel.prototype._isFilteredBySearchText = function() { return !!this._getSearchText().length; }; P13nSelectionPanel.prototype._isFilteredByShowSelected = function() { return false; }; P13nSelectionPanel.prototype._updateControlLogic = function() { var bIsSearchActive = this._isFilteredBySearchText(); var bShowOnlySelectedItems = this._isFilteredByShowSelected(); // Switch off the "Select all (n/m)" checkbox if search var oTableCB = sap.ui.getCore().byId(this._oTable.getId() + '-sa'); if (oTableCB) { oTableCB.setEnabled(!bIsSearchActive && !bShowOnlySelectedItems); } }; P13nSelectionPanel.prototype._fireChangeSelectionItems = function() { this._bIgnoreUpdateInternalModel = true; var aMItems = this._getInternalModel().getProperty("/items"); this.fireChangeSelectionItems({ items: aMItems.map(function(oMItem) { return { columnKey: oMItem.columnKey, selected: oMItem.persistentSelected }; }) }); this._bIgnoreUpdateInternalModel = false; }; P13nSelectionPanel.prototype._onSelectionChange = function() { this._selectTableItem(); }; P13nSelectionPanel.prototype._selectTableItem = function() { // No update of model items is needed as it is already up-to-date due to binding of 'persistentSelected' // Do not sort after user interaction as the table should not be sorted once selected items has been rendered var aMItems = this._getInternalModel().getProperty("/items"); this._updateCounts(aMItems); this._getInternalModel().setProperty("/items", aMItems); this._fireChangeSelectionItems(); this._notifyChange(); }; P13nSelectionPanel.prototype._filterModelItemsBySearchText = function() { var sSearchText = this._getSearchText(); // Replace white spaces at begin and end of the searchText. Leave white spaces in between. sSearchText = sSearchText.replace(/(^\s+)|(\s+$)/g, ''); // Escape special characters entered by user sSearchText = sSearchText.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); // i = ignore case; g = global; m = multiline var oRegExp = new RegExp(sSearchText, 'igm'); this._getVisibleModelItems().forEach(function(oMItem) { oMItem.visible = false; // Search in item text if (oMItem.text && oMItem.text.match(oRegExp)) { oMItem.visible = true; } // Search in tooltip if (oMItem.tooltip && oMItem.tooltip.match(oRegExp)) { oMItem.visible = true; } }); this._getInternalModel().refresh(); }; /** * Synchronize <code>selectionItems</code> and <code>items</code> aggregations with the internal JSON model * and take over data from the model of aggregation binding. * @private */ P13nSelectionPanel.prototype._updateInternalModel = function() { if (!this._bUpdateInternalModel) { return; } this._bUpdateInternalModel = false; this._getInternalModel().setProperty("/items", this.getItems().map(function(oItem) { return { columnKey: oItem.getColumnKey(), visible: true, text: oItem.getText(), tooltip: oItem.getTooltip(), href: oItem.getHref(), target: oItem.getTarget(), // default value persistentSelected: oItem.getVisible(), description: oItem.getDescription() }; }, this)); this.getSelectionItems().forEach(function(oSelectionItem) { var oMItem = this._getModelItemByColumnKey(oSelectionItem.getColumnKey()); if (!oMItem) { return; } if (oSelectionItem.getSelected() !== undefined) { oMItem.persistentSelected = oSelectionItem.getSelected(); } }, this); this._switchVisibilityOfUnselectedModelItems(); this._filterModelItemsBySearchText(); var aMItems = this._getInternalModel().getProperty("/items"); this._updateCounts(aMItems); this._getInternalModel().setProperty("/items", aMItems); }; return P13nSelectionPanel; });