DVHMA/DVHMA-OpenUI5/www/resources/sap/m/ComboBoxBase-dbg.js

874 lines
25 KiB
JavaScript

/*!
* SAP UI development toolkit for HTML5 (SAPUI5/OpenUI5)
* (c) Copyright 2009-2015 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
// Provides control sap.m.ComboBoxBase.
sap.ui.define(['jquery.sap.global', './Bar', './ComboBoxBaseRenderer', './Dialog', './InputBase', './List', './Popover', './library', 'sap/ui/core/EnabledPropagator', 'sap/ui/core/IconPool'],
function(jQuery, Bar, ComboBoxBaseRenderer, Dialog, InputBase, List, Popover, library, EnabledPropagator, IconPool) {
"use strict";
/**
* Constructor for a new ComboBoxBase.
*
* @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
* An abstract class for ComboBoxes.
* @extends sap.m.InputBase
*
* @author SAP SE
* @version 1.28.5
*
* @constructor
* @public
* @since 1.22.0
* @alias sap.m.ComboBoxBase
* @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
*/
var ComboBoxBase = InputBase.extend("sap.m.ComboBoxBase", /** @lends sap.m.ComboBoxBase.prototype */ { metadata: {
"abstract": true,
library: "sap.m",
properties: {
/**
* Defines the maximum width of the text field. This value can be provided in %, em, px… and all CSS units.
*/
maxWidth: { type: "sap.ui.core.CSSSize", group: "Dimension", defaultValue: "100%" }
},
defaultAggregation: "items",
aggregations: {
/**
* Aggregation of items to be displayed.
*/
items: { type: "sap.ui.core.Item", multiple: true, singularName: "item", bindable: "bindable" },
/**
* Internal aggregation to hold the inner picker pop-up.
*/
picker: { type: "sap.ui.core.Control", multiple: false, visibility: "hidden" }
}
}});
IconPool.insertFontFaceStyle();
EnabledPropagator.apply(ComboBoxBase.prototype, [true]);
/* =========================================================== */
/* Private methods and properties */
/* =========================================================== */
/* ----------------------------------------------------------- */
/* Private methods */
/* ----------------------------------------------------------- */
/**
* Given an item, retrieve the corresponding list item.
*
* @param {sap.ui.core.Item} vItem
* @returns {sap.m.StandardListItem | null}
*/
ComboBoxBase.prototype.getListItem = function(oItem) {
return (oItem && oItem.data(sap.m.ComboBoxBaseRenderer.CSS_CLASS + "ListItem")) || null;
};
/**
* Map an item type of sap.ui.core.Item to an item type of sap.m.StandardListItem.
*
* @param {sap.ui.core.Item} oItem
* @returns {sap.m.StandardListItem | null}
* @private
*/
ComboBoxBase.prototype._mapItemToListItem = function(oItem) {
if (!oItem) {
return null;
}
var CSS_CLASS = ComboBoxBaseRenderer.CSS_CLASS,
sListItem = CSS_CLASS + "Item",
sListItemEnabled = oItem.getEnabled() ? "Enabled" : "Disabled",
sListItemSelected = (oItem === this.getSelectedItem()) ? sListItem + "Selected" : "",
oListItem = this.getListItem(oItem),
bItemVisible = oListItem ? oListItem.getVisible() : true;
oListItem = new sap.m.StandardListItem().addStyleClass(sListItem + " " + sListItem + sListItemEnabled + " " + sListItemSelected);
oListItem.setVisible(bItemVisible);
oListItem.setTitle(oItem.getText());
oListItem.setType(oItem.getEnabled() ? sap.m.ListType.Active : sap.m.ListType.Inactive);
oListItem.setTooltip(oItem.getTooltip());
oItem.data(CSS_CLASS + "ListItem", oListItem);
return oListItem;
};
/**
* Given an item type of sap.m.StandardListItem, find the corresponding item type of sap.ui.core.Item.
*
* @param {sap.m.StandardListItem} oListItem
* @param {array} [aItems]
* @returns {sap.ui.core.Item | null}
* @private
*/
ComboBoxBase.prototype._findMappedItem = function(oListItem, aItems) {
for (var i = 0, aItems = aItems || this.getItems(), aItemsLength = aItems.length; i < aItemsLength; i++) {
if (this.getListItem(aItems[i]) === oListItem) {
return aItems[i];
}
}
return null;
};
/**
* Fill the List.
*
* @param {sap.ui.core.Item[]} aItems
* @private
*/
ComboBoxBase.prototype._fillList = function(aItems) {
var oSelectedItem = this.getSelectedItem();
for (var i = 0, oListItem, oItem; i < aItems.length; i++) {
oItem = aItems[i];
// add a private property to the added item containing a reference
// to the corresponding mapped item
oListItem = this._mapItemToListItem(oItem);
// add the mapped item type of sap.m.StandardListItem to the List
this.getList().addAggregation("items", oListItem, true); // note: suppress re-rendering
// add active state to the selected item
if (oItem === oSelectedItem) {
this.getList().setSelectedItem(oListItem, true);
}
}
};
/**
* Destroy the items in the List.
*
* @private
*/
ComboBoxBase.prototype._clearList = function() {
if (this.getList()) {
this.getList().destroyAggregation("items", true); // note: suppress re-rendering
}
};
/**
* Getter for the control's List.
*
* @returns {sap.m.List}
* @private
*/
ComboBoxBase.prototype.getList = function() {
return this._oList;
};
/* =========================================================== */
/* Lifecycle methods */
/* =========================================================== */
/**
* Initialization hook.
*
* @private
*/
ComboBoxBase.prototype.init = function() {
InputBase.prototype.init.apply(this, arguments);
// set the picker pop-up type
this.setPickerType("Popover");
// initialize list
this.createList();
};
/**
* Cleans up before destruction.
*
* @private
*/
ComboBoxBase.prototype.exit = function() {
InputBase.prototype.exit.apply(this, arguments);
if (this.getList()) {
this.getList().destroy();
this._oList = null;
}
};
/* =========================================================== */
/* Event handlers */
/* =========================================================== */
/**
* Handle the touch start event on the control.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBoxBase.prototype.ontouchstart = function(oEvent) {
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
if (this.isOpenArea(oEvent.target)) {
// add the active state to the control's field
this.addStyleClass(ComboBoxBaseRenderer.CSS_CLASS + "Pressed");
}
};
/**
* Handle the touch end event on the control.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBoxBase.prototype.ontouchend = function(oEvent) {
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
if ((!this.isOpen() || !this.hasContent()) && this.isOpenArea(oEvent.target)) {
// remove the active state of the control's field
this.removeStyleClass(ComboBoxBaseRenderer.CSS_CLASS + "Pressed");
}
};
/**
* Handle the tap event on the control.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBoxBase.prototype.ontap = function(oEvent) {
var CSS_CLASS = ComboBoxBaseRenderer.CSS_CLASS;
// a non editable or disabled ComboBox, the picker pop-up cannot be opened
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
if (this.isOpenArea(oEvent.target)) {
if (this.isOpen()) {
this.close();
this.removeStyleClass(CSS_CLASS + "Pressed");
return;
}
if (this.hasContent()) {
this.open();
}
}
if (this.isOpen()) {
// add the active state to the control's field
this.addStyleClass(CSS_CLASS + "Pressed");
}
};
/* ----------------------------------------------------------- */
/* Keyboard handling */
/* ----------------------------------------------------------- */
/**
* Handle when F4 or Alt + DOWN arrow are pressed.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBoxBase.prototype.onsapshow = function(oEvent) {
// a non editable or disabled ComboBox, the picker pop-up cannot be opened
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// note: prevent browser address bar to be open in ie9, when F4 is pressed
if (oEvent.keyCode === jQuery.sap.KeyCodes.F4) {
oEvent.preventDefault();
}
if (this.isOpen()) {
this.close();
return;
}
// select all text
this.selectText(0, this.getValue().length);
// open only if the combobox has items
if (this.hasContent()) {
this.open();
}
};
/**
* Handle when escape is pressed.
*
* If picker pop-up is closed, cancel changes and revert to the value which
* the input field had when it got the focus.
* If List is open, close list.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBoxBase.prototype.onsapescape = function(oEvent) {
// a non editable or disabled ComboBox, the value cannot be changed
if (this.getEnabled() && this.getEditable() && this.isOpen()) {
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// note: fix for Firefox
oEvent.preventDefault();
this.close();
} else { // the picker is closed
// cancel changes and revert to the value which the Input field had when it got the focus
InputBase.prototype.onsapescape.apply(this, arguments);
}
};
/**
* Handle when Alt + UP arrow are pressed.
*
* @param {jQuery.Event} oEvent The event object.
* @private
* @function
*/
ComboBoxBase.prototype.onsaphide = ComboBoxBase.prototype.onsapshow;
/* =========================================================== */
/* API methods */
/* =========================================================== */
/* ----------------------------------------------------------- */
/* protected methods */
/* ----------------------------------------------------------- */
/*
* Hook method, can be used to add additional content to the control's picker pop-up.
*
* @param {sap.m.Dialog | sap.m.Popover} [oPicker]
* @protected
*/
ComboBoxBase.prototype.addContent = function(oPicker) {};
/**
* Setter for property <code>_sPickerType</code>.
*
* @param {string} sPickerType
* @protected
*/
ComboBoxBase.prototype.setPickerType = function(sPickerType) {
this._sPickerType = sPickerType;
};
/**
* Getter for property <code>_sPickerType</code>
*
* @returns {string}
* @protected
*/
ComboBoxBase.prototype.getPickerType = function() {
return this._sPickerType;
};
/**
* Creates a picker.
* To be overwritten by subclasses.
*
* @param {string} sPickerType
* @returns {sap.m.Popover | sap.m.Dialog} The picker pop-up to be used.
* @protected
*/
ComboBoxBase.prototype.createPicker = function() {};
/**
* Getter for the control's picker pop-up.
*
* @returns {sap.m.Dialog | sap.m.Popover | null} The picker instance, creating it if necessary by calling <code>createPicker()</code> method.
* @protected
*/
ComboBoxBase.prototype.getPicker = function() {
if (this.bIsDestroyed) {
return null;
}
// initialize the control's picker
return this.createPicker(this.getPickerType());
};
/*
* Determines whether the control has content or not.
*
* @returns {boolean}
* @protected
*/
ComboBoxBase.prototype.hasContent = function() {
return !!this.getItems().length;
};
/*
* Retrieves the first enabled item from the aggregation named <code>items</code>.
*
* @param {array} [aItems]
* @returns {sap.ui.core.Item | null}
* @protected
*/
ComboBoxBase.prototype.findFirstEnabledItem = function(aItems) {
aItems = aItems || this.getItems();
for (var i = 0; i < aItems.length; i++) {
if (aItems[i].getEnabled()) {
return aItems[i];
}
}
return null;
};
/*
* Retrieves the last enabled item from the aggregation named <code>items</code>.
*
* @param {array} [aItems]
* @returns {sap.ui.core.Item | null}
* @protected
*/
ComboBoxBase.prototype.findLastEnabledItem = function(aItems) {
aItems = aItems || this.getItems();
return this.findFirstEnabledItem(aItems.reverse());
};
/*
* Open the control's picker pop-up.
*
* @returns {sap.m.ComboBoxBase} <code>this</code> to allow method chaining.
* @protected
*/
ComboBoxBase.prototype.open = function() {
var oPicker = this.getPicker();
if (oPicker) {
oPicker.open();
}
return this;
};
/*
* Getter for visible <code>items</code>.
*
* @return {sap.ui.core.Item[]}
* @protected
*/
ComboBoxBase.prototype.getVisibleItems = function() {
for (var i = 0, oListItem, aItems = this.getItems(), aVisibleItems = []; i < aItems.length; i++) {
oListItem = this.getListItem(aItems[i]);
if (oListItem && oListItem.getVisible()) {
aVisibleItems.push(aItems[i]);
}
}
return aVisibleItems;
};
/*
* Check whether an item is selected or not.
* To be overwritten by subclasses.
*
* @param {sap.ui.core.Item} oItem
* @returns {boolean} Whether the item is selected.
* @protected
* @since 1.24.0
* @name sap.m.ComboBoxBase#isItemSelected
* @function
*/
ComboBoxBase.prototype.isItemSelected = function() {};
/*
* Get key of each item from the aggregation named items.
*
* @param {sap.ui.core.Item[]} [aItems]
* @return {string[]}
* @protected
* @since 1.24.0
* @name sap.m.ComboBoxBase#getKeys
* @function
*/
ComboBoxBase.prototype.getKeys = function(aItems) {
for (var i = 0, aKeys = [], aItems = aItems || this.getItems(); i < aItems.length; i++) {
aKeys[i] = aItems[i].getKey();
}
return aKeys;
};
/*
* Retrieves the selectables items from the aggregation named <code>items</code>.
*
* @returns {sap.ui.core.Item[]} An array containing the selectables items.
* @protected
*/
ComboBoxBase.prototype.getSelectableItems = function() {
return this.getEnabledItems(this.getVisibleItems());
};
/*
* Getter for the control's picker pop-up open area element.
*
* @returns {Element | null} Returns the element that is used as trigger to open the control's picker pop-up.
* @protected
*/
ComboBoxBase.prototype.getOpenArea = function() {
return this.getDomRef("arrow");
};
/*
* Checks whether the provided element is the open area.
*
* @param {Element} oDomRef
* @returns {boolean}
* @protected
*/
ComboBoxBase.prototype.isOpenArea = function(oDomRef) {
var oOpenAreaDomRef = this.getOpenArea();
return oOpenAreaDomRef && oOpenAreaDomRef.contains(oDomRef);
};
/*
* Retrieves a item by searching for the given property/value from the aggregation named <code>items</code>.
* If duplicate values exist, the first item matching the value is returned.
*
* @param {string} sProperty An item property.
* @param {string} sValue An item value that specifies the item to retrieve.
* @returns {sap.ui.core.Item | null} The matched item or null.
* @protected
*/
ComboBoxBase.prototype.findItem = function(sProperty, sValue) {
var sMethod = "get" + sProperty.charAt(0).toUpperCase() + sProperty.slice(1);
for (var i = 0, aItems = this.getItems(); i < aItems.length; i++) {
if (aItems[i][sMethod]() === sValue) {
return aItems[i];
}
}
return null;
};
/*
* Retrieves the item with the given value from the aggregation named <code>items</code>.
* If duplicate values exist, the first item matching the value is returned.
*
* @param {string} sText An item value that specifies the item to retrieve.
* @returns {sap.ui.core.Item | null} The matched item or null.
* @protected
*/
ComboBoxBase.prototype.getItemByText = function(sText) {
return this.findItem("text", sText);
};
/*
* Scrolls an item into the visual viewport.
*
* @protected
*/
ComboBoxBase.prototype.scrollToItem = function(oItem) {
var oPicker = this.getPicker(),
oPickerDomRef = oPicker.getDomRef("cont"),
oItemDomRef = oItem && oItem.getDomRef();
if (!oPicker || !oPickerDomRef || !oItemDomRef) {
return;
}
var iPickerScrollTop = oPickerDomRef.scrollTop,
iItemOffsetTop = oItemDomRef.offsetTop,
iPickerHeight = oPickerDomRef.clientHeight,
iItemHeight = oItemDomRef.offsetHeight;
if (iPickerScrollTop > iItemOffsetTop) {
// scroll up
oPickerDomRef.scrollTop = iItemOffsetTop;
// bottom edge of item > bottom edge of viewport
} else if ((iItemOffsetTop + iItemHeight) > (iPickerScrollTop + iPickerHeight)) {
// scroll down, the item is partly below the viewport of the List
oPickerDomRef.scrollTop = Math.ceil(iItemOffsetTop + iItemHeight - iPickerHeight);
}
};
/*
* Clear the filter
*
* @protected
*/
ComboBoxBase.prototype.clearFilter = function() {
for (var i = 0, oListItem, aItems = this.getItems(); i < aItems.length; i++) {
oListItem = this.getListItem(aItems[i]);
oListItem.setVisible(true);
}
};
/*
* Clear the selection.
* To be overwritten by subclasses.
*
* @protected
*/
ComboBoxBase.prototype.clearSelection = function() {};
/* ----------------------------------------------------------- */
/* public methods */
/* ----------------------------------------------------------- */
/**
* Getter for property <code>value</code>.
* Defines the value of the control's input field.
*
* Default value is empty/<code>undefined</code>
*
* @return {string} the value of property <code>value</code>
* @public
*/
ComboBoxBase.prototype.getValue = function() {
var oDomRef = this.getFocusDomRef();
// if the input field is rendered
if (oDomRef) {
// return the live value
return oDomRef.value;
}
// else return the value from the model
return this.getProperty("value");
};
/**
* Adds some item <code>oItem</code> to the aggregation named <code>items</code>.
*
* @param {sap.ui.core.Item} oItem The item to add; if empty, nothing is added.
* @returns {sap.m.ComboBoxBase} <code>this</code> to allow method chaining.
* @public
*/
ComboBoxBase.prototype.addItem = function(oItem) {
this.addAggregation("items", oItem);
if (this.getList()) {
this.getList().addItem(this._mapItemToListItem(oItem));
}
return this;
};
/**
* Inserts an item into the aggregation named <code>items</code>.
*
* @param {sap.ui.core.Item} oItem The item to insert; if empty, nothing is inserted.
* @param {int} iIndex The <code>0</code>-based index the item should be inserted at; for
* a negative value of <code>iIndex</code>, the item is inserted at position 0; for a value
* greater than the current size of the aggregation, the item is inserted at
* the last position.
* @returns {sap.m.ComboBoxBase} <code>this</code> to allow method chaining.
* @public
*/
ComboBoxBase.prototype.insertItem = function(oItem, iIndex) {
this.insertAggregation("items", oItem, iIndex);
if (this.getList()) {
this.getList().insertItem(this._mapItemToListItem(oItem), iIndex);
}
return this;
};
/**
* Retrieves the item from the aggregation named <code>items</code> at the given 0-based index.
*
* @param {int} iIndex Index of the item to return.
* @returns {sap.ui.core.Item} Item at the given index, or null if none.
* @public
* @ui5-metamodel This method also will be described in the UI5 (legacy) designtime metamodel
*/
ComboBoxBase.prototype.getItemAt = function(iIndex) {
return this.getItems()[ +iIndex] || null;
};
/**
* Retrieves the first item from the aggregation named <code>items</code>.
*
* @returns {sap.ui.core.Item} The first item, or null if there are no items.
* @public
* @ui5-metamodel This method also will be described in the UI5 (legacy) designtime metamodel
*/
ComboBoxBase.prototype.getFirstItem = function() {
return this.getItems()[0] || null;
};
/**
* Retrieves the last item from the aggregation named <code>items</code>.
*
* @returns {sap.ui.core.Item} The last item, or null if there are no items.
* @public
* @ui5-metamodel This method also will be described in the UI5 (legacy) designtime metamodel
*/
ComboBoxBase.prototype.getLastItem = function() {
var aItems = this.getItems();
return aItems[aItems.length - 1] || null;
};
/**
* Retrieves the enabled items from the given array of items or from
* this control's aggregation named <code>items</code>.
*
* @param {sap.ui.core.Item[]} [aItems=getItems()] Items to filter.
* @return {sap.ui.core.Item[]} An array containing the enabled items.
* @public
* @ui5-metamodel This method also will be described in the UI5 (legacy) designtime metamodel
*/
ComboBoxBase.prototype.getEnabledItems = function(aItems) {
aItems = aItems || this.getItems();
return aItems.filter(function(oItem) {
return oItem.getEnabled();
});
};
/**
* Retrieves the item with the given key from the aggregation named <code>items</code>.
* If duplicate keys exist, the first item matching the key is returned.
*
* @param {string} sKey An item key that specifies the item to retrieve.
* @returns {sap.ui.core.Item}
* @public
* @ui5-metamodel This method also will be described in the UI5 (legacy) designtime metamodel
*/
ComboBoxBase.prototype.getItemByKey = function(sKey) {
return this.findItem("key", sKey);
};
/**
* Whether the control's picker pop-up is open. It returns true when the control's picker pop-up is currently open,
* this includes opening and closing animations.
*
* @returns {boolean} Determines whether the control's picker pop-up is currently open (this includes opening and closing animations).
* @public
* @ui5-metamodel This method also will be described in the UI5 (legacy) designtime metamodel
*/
ComboBoxBase.prototype.isOpen = function() {
var oPicker = this.getAggregation("picker");
return !!(oPicker && oPicker.isOpen());
};
/**
* Closes the control's picker pop-up.
*
* @returns {sap.m.ComboBoxBase} <code>this</code> to allow method chaining.
* @public
* @ui5-metamodel This method also will be described in the UI5 (legacy) designtime metamodel
*/
ComboBoxBase.prototype.close = function() {
var oPicker = this.getAggregation("picker");
if (oPicker) {
oPicker.close();
}
return this;
};
/**
* Removes an item from the aggregation named <code>items</code>.
*
* @param {int | string | sap.ui.core.Item} vItem The item to remove or its index or id.
* @returns {sap.ui.core.Item} The removed item or null.
* @public
*/
ComboBoxBase.prototype.removeItem = function(vItem) {
// remove the item from the aggregation items
vItem = this.removeAggregation("items", vItem);
// remove the corresponding mapped item from the List
if (this.getList()) {
this.getList().removeItem(this.getListItem(vItem));
}
// return the removed item or null
return vItem;
};
/**
* Removes all the controls in the aggregation named <code>items</code>.
* Additionally unregisters them from the hosting UIArea and clears the selection.
*
* @returns {sap.ui.core.Item[]} An array of the removed items (might be empty).
* @public
*/
ComboBoxBase.prototype.removeAllItems = function() {
var aItems = this.removeAllAggregation("items");
// clear the selection
this.clearSelection();
if (this.getList()) {
this.getList().removeAllItems();
}
return aItems;
};
/**
* Destroys all the items in the aggregation named <code>items</code>.
*
* @returns {sap.m.ComboBox} <code>this</code> to allow method chaining.
* @public
*/
ComboBoxBase.prototype.destroyItems = function() {
this.destroyAggregation("items");
if (this.getList()) {
this.getList().destroyItems();
}
return this;
};
return ComboBoxBase;
}, /* bExport= */ true);