UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

315 lines (281 loc) 7.85 kB
/*! * 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([ "./Toolbar", "./Button", "./Dialog", "./Popover", "./SuggestionsList", "./SuggestionItem", "sap/ui/Device", "sap/m/library", "sap/ui/core/InvisibleText", "sap/ui/core/Lib" ], function ( Toolbar, Button, Dialog, Popover, SuggestionsList, SuggestionItem, Device, library, InvisibleText, Library ) { "use strict"; // shortcut for sap.m.PlacementType var PlacementType = library.PlacementType; /** * <code>sap.m.Suggest</code> provides the functionality to display suggestion lists for the user entry * in a search field. * * This function is part of the sap.m.SearchField functionality. * It should not be used in application programming as a stand alone unit. * * @author SAP SE * @since 1.34 * * @private * @alias sap.m.Suggest * * @param {sap.ui.core.Control} oInput the search/input control to which this suggestion belongs * * @constructor */ function Suggest(oInput) { var parent = oInput, // the parent search field/input picker, // either or popover or a dialog with the list of suggestion items list, // SuggestionsList with suggestions listUpdateTimeout, // list is updated after a timeout to accumulate simultaneous updates bUseDialog = Device.system.phone, self = this; /* =========================================================== */ /* events processing */ /* =========================================================== */ // Process tap over a list item in a picker function ontap(oEvent) { var item = oEvent.srcControl; var value; if (item instanceof SuggestionItem ) { value = item.getSuggestionText(); self._suggestionItemTapped = true; picker.close(); window.setTimeout(function() { oInput._updateValue(value); oInput._fireChangeEvent(); oInput.fireSearch({ query: value, suggestionItem: item, refreshButtonPressed: false, clearButtonPressed: false }); }, 0); } } /* =========================================================== */ /* internal helper functions */ /* =========================================================== */ function createDialog() { var dialog, originalValue, dialogSearchField, customHeader, okButton, closeButton; // use sap.ui.require to avoid circular dependency between the SearchField and Suggest dialogSearchField = new (sap.ui.require('sap/m/SearchField'))({ liveChange : function (oEvent) { var value = oEvent.getParameter("newValue"); oInput._updateValue(value); oInput.fireLiveChange({newValue: value}); oInput.fireSuggest({suggestValue: value}); self.update(); }, search : function (oEvent) { if (!oEvent.getParameter("clearButtonPressed")) { dialog.close(); } } }); closeButton = new Button({ icon : "sap-icon://decline", press : function() { self._cancelButtonTapped = true; dialog._oCloseTrigger = true; dialog.close(); oInput._updateValue(originalValue); } }); customHeader = new Toolbar({ content: [dialogSearchField, closeButton] }); okButton = new Button({ text : Library.getResourceBundleFor("sap.m").getText("MSGBOX_OK"), press : function() { dialog.close(); } }); dialog = new Dialog({ stretch: true, customHeader: customHeader, content: getList(), beginButton : okButton, beforeClose: function () { oInput._bSuggestionSuppressed = true; }, beforeOpen: function() { originalValue = oInput.getValue(); dialogSearchField._updateValue(originalValue); }, afterClose: function(oEvent) { if (!self._cancelButtonTapped // fire the search event if not cancelled && !self._suggestionItemTapped) { // and if not closed from item tap oInput._fireChangeEvent(); oInput.fireSearch({ query: oInput.getValue(), refreshButtonPressed: false, clearButtonPressed: false }); } } }); dialog.addEventDelegate({ ontap: ontap }, oInput); return dialog; } function createPopover() { var popover = self._oPopover = new Popover({ showArrow: false, showHeader: false, horizontalScrolling: false, placement: PlacementType.Vertical, offsetX: 0, offsetY: 0, initialFocus: parent, ariaLabelledBy: InvisibleText.getStaticId("sap.m", "INPUT_AVALIABLE_VALUES"), afterOpen: function () { oInput._applySuggestionAcc(); }, beforeClose: function() { oInput.$("I").removeAttr("aria-activedescendant"); oInput.$("SuggDescr").text(""); }, content: getList() }) .addStyleClass("sapMSltPicker") .addStyleClass("sapMSltPicker-CTX"); popover.open = function(){ return this.openBy(parent); }; popover.addEventDelegate({ onAfterRendering: self.setPopoverMinWidth.bind(self), ontap: ontap }, oInput); return popover; } function getList() { if (!list) { list = new SuggestionsList({ parentInput: parent }); } return list; } function getPicker() { if (picker === undefined) { picker = bUseDialog ? createDialog() : createPopover(); } return picker; } /* =========================================================== */ /* API functions */ /* =========================================================== */ this.setPopoverMinWidth = function() { var oPopoverDomRef = self._oPopover.getDomRef(); var iShadow = self._oPopover._fThickShadowSize; if (oPopoverDomRef) { var w = ((oInput.$().outerWidth() - (iShadow * 2)) / parseFloat(library.BaseFontSize)) + "rem"; oPopoverDomRef.style.minWidth = w; } }; this.destroy = function() { if (picker) { picker.close(); picker.destroy(); picker = null; } if (list) { list.destroy(); list = null; } }; /** * Hide suggestions on desktop and tablets. * * Note: This function does nothing on phone devices where a full screen dialog is opened. * Only the user may close the full screen dialog. There is no possibility to do it from the application code. * * @private */ this.close = function() { if (!bUseDialog && this.isOpen()) { picker.close(); } }; /** * Show suggestions. * * @private */ this.open = function() { if (!this.isOpen()) { this.setSelected(-1); // clear selection before open this._suggestionItemTapped = false; this._cancelButtonTapped = false; getPicker().open(); } }; /** * Update the suggestions list display. * * @private */ this.update = function() { var list = getList(); window.clearTimeout(listUpdateTimeout); if (this.isOpen()) { // redraw the list only if it is visible listUpdateTimeout = window.setTimeout(list.update.bind(list), 50); oInput._applySuggestionAcc(); } }; /** * @returns {boolean} true if the suggestions list is visible. * @private */ this.isOpen = function() { return !!picker && picker.isOpen(); }; /** * Getter for the selected item index. * * @returns {int} Index of the selected item or -1 * @private */ this.getSelected = function() { return getList().getSelectedItemIndex(); }; /** * Setter for the selected item index. * * @param {int} index Index of the item to select or -1 to remove selection * @private */ this.setSelected = function(index, bRelative) { return getList().selectByIndex(index, bRelative); }; }/* Suggest */ return Suggest; }, /* bExport= */ true);