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

1195 lines
35 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.ComboBox.
sap.ui.define(['jquery.sap.global', './ComboBoxBase', './ComboBoxRenderer', './library'],
function(jQuery, ComboBoxBase, ComboBoxRenderer, library) {
"use strict";
/**
* Constructor for a new ComboBox.
*
* @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 ComboBox control provides a list box with items and a text field allowing the user to either type a value directly into the control or choose from the list of existing items.
* @extends sap.m.ComboBoxBase
*
* @author SAP SE
* @version 1.28.5
*
* @constructor
* @public
* @since 1.22
* @alias sap.m.ComboBox
* @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
*/
var ComboBox = ComboBoxBase.extend("sap.m.ComboBox", /** @lends sap.m.ComboBox.prototype */ { metadata: {
library: "sap.m",
properties: {
/**
* Key of the selected item. If the key has no corresponding item, no changes will apply. If duplicate keys exist, the first item matching the key is used.
*/
selectedKey: { type: "string", group: "Data", defaultValue: "" },
/**
* Identifier of the selected item. If the identifier has no corresponding item, no changes will apply.
*/
selectedItemId: { type: "string", group: "Misc", defaultValue: "" }
},
associations: {
/**
* Sets or retrieves the selected item from the aggregation named items.
*/
selectedItem: { type: "sap.ui.core.Item", multiple: false }
},
events: {
/**
* Occurs when the user changes the selected item.
*/
selectionChange: {
parameters: {
/**
* The selected item.
*/
selectedItem: { type: "sap.ui.core.Item" }
}
}
}
}});
/* =========================================================== */
/* Private methods and properties */
/* =========================================================== */
/* ----------------------------------------------------------- */
/* Private methods */
/* ----------------------------------------------------------- */
function fnHandleKeyboardNavigation(oItem) {
var oDomRef = this.getFocusDomRef(),
iSelectionStart = oDomRef.selectionStart,
iSelectionEnd = oDomRef.selectionEnd,
bIsTextSelected = iSelectionStart !== iSelectionEnd,
sTypedValue = oDomRef.value.substring(0, oDomRef.selectionStart),
oSelectedItem = this.getSelectedItem();
if (oItem && (oItem !== oSelectedItem)) {
this.updateDomValue(oItem.getText());
this.setSelection(oItem, { suppressInvalidate: true });
this.fireSelectionChange({ selectedItem: oItem });
oItem = this.getSelectedItem(); // note: update the selected item after the change event is fired (the selection may change)
if (!jQuery.sap.startsWithIgnoreCase(oItem.getText(), sTypedValue) || !bIsTextSelected) {
iSelectionStart = 0;
}
this.selectText(iSelectionStart, oDomRef.value.length);
}
this.scrollToItem(this.getList().getSelectedItem());
}
/* ----------------------------------------------------------- */
/* Popover */
/* ----------------------------------------------------------- */
/**
* Creates an instance type of <code>sap.m.Popover</code>.
*
* @returns {sap.m.Popover}
* @private
*/
ComboBox.prototype._createPopover = function() {
// initialize Popover
var oPicker = new sap.m.Popover({
showHeader: false,
placement: sap.m.PlacementType.Vertical,
offsetX: 0,
offsetY: 0,
initialFocus: this,
bounce: false
});
this._decoratePopover(oPicker);
return oPicker;
};
/**
* Decorate a Popover instance by adding some private methods.
*
* @param {sap.m.Popover}
* @private
*/
ComboBox.prototype._decoratePopover = function(oPopover) {
var that = this;
// adding additional capabilities to the Popover
oPopover._removeArrow = function() {
this._marginTop = 0;
this._marginLeft = 0;
this._marginRight = 0;
this._marginBottom = 0;
this._arrowOffset = 0;
this._offsets = ["0 0", "0 0", "0 0", "0 0"];
};
oPopover._setPosition = function() {
this._myPositions = ["begin bottom", "begin center", "begin top", "end center"];
this._atPositions = ["begin top", "end center", "begin bottom", "begin center"];
};
oPopover._setArrowPosition = function() {};
oPopover.open = function() {
return this.openBy(that.getFocusDomRef());
};
};
/**
* Required adaptations after rendering of the Popover.
*
* @private
*/
ComboBox.prototype.onAfterRenderingPopover = function() {
var oPopover = this.getPicker();
// remove the Popover arrow
oPopover._removeArrow();
// position adaptations
oPopover._setPosition();
};
/* ----------------------------------------------------------- */
/* Dialog */
/* ----------------------------------------------------------- */
/**
* Creates an instance type of <code>sap.m.Dialog</code>.
*
* @returns {sap.m.Dialog}
* @private
*/
ComboBox.prototype._createDialog = function() {
var CSS_CLASS = sap.m.ComboBoxBaseRenderer.CSS_CLASS;
// initialize Dialog
var oDialog = new sap.m.Dialog({
stretchOnPhone: true,
customHeader: new sap.m.Bar({
contentLeft: new sap.m.InputBase({
value: this.getSelectedItem().getText(),
width: "100%",
editable: false
}).addStyleClass(CSS_CLASS + "Input")
}).addStyleClass(CSS_CLASS + "Bar")
});
oDialog.getAggregation("customHeader").attachBrowserEvent("tap", function() {
oDialog.close();
}, this);
return oDialog;
};
/**
* Called before the Dialog is opened.
*
* @private
*/
ComboBox.prototype.onBeforeOpenDialog = function() {
var oHeader = this.getPicker().getCustomHeader();
oHeader.getContentLeft()[0].setValue(this.getSelectedItem().getText());
};
/* =========================================================== */
/* Lifecycle methods */
/* =========================================================== */
/**
* Required adaptations before rendering.
*
* @private
*/
ComboBox.prototype.onBeforeRendering = function() {
ComboBoxBase.prototype.onBeforeRendering.apply(this, arguments);
this.synchronizeSelection();
this._clearList();
this._fillList(this.getItems());
};
/* =========================================================== */
/* Event handlers */
/* =========================================================== */
/**
* Handle the input event on the control's input field.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.oninput = function(oEvent) {
ComboBoxBase.prototype.oninput.apply(this, arguments);
// note: suppress input events of read-only fields (IE11)
if (!this.getEditable()) {
return;
}
var oSelectedItem = this.getSelectedItem(),
aItems = this.getItems(),
oInputDomRef = oEvent.target,
sValue = oInputDomRef.value,
bFirst = true,
bVisibleItems = false,
oItem,
bMatch,
oListItem,
i = 0;
for (; i < aItems.length; i++) {
// the item match with the value
oItem = aItems[i];
bMatch = jQuery.sap.startsWithIgnoreCase(oItem.getText(), sValue);
oListItem = this.getListItem(oItem);
if (sValue === "") {
bMatch = true;
}
// toggle the visibility of the items according to the value
oListItem.setVisible(bMatch);
if (bMatch && !bVisibleItems) {
bVisibleItems = true;
}
// first match of the value
if (bFirst && bMatch && sValue !== "") {
bFirst = false;
if (this._bDoTypeAhead) {
this.updateDomValue(oItem.getText());
}
this.setSelection(oItem, { suppressInvalidate: true });
if (oSelectedItem !== this.getSelectedItem()) {
this.fireSelectionChange({ selectedItem: this.getSelectedItem() });
}
if (this._bDoTypeAhead) {
this.selectText(sValue.length, 9999999);
}
this.scrollToItem(this.getList().getSelectedItem());
}
}
if (sValue === "" || !bVisibleItems) {
this.setSelection(null, { suppressInvalidate: true });
if (oSelectedItem !== this.getSelectedItem()) {
this.fireSelectionChange({ selectedItem: this.getSelectedItem() });
}
}
// open the picker on input
if (bVisibleItems) {
this.open();
} else {
this.isOpen() ? this.close() : this.clearFilter();
}
};
/**
* Handle the selection change event on the List.
*
* @param {sap.ui.base.Event} oControlEvent
* @private
*/
ComboBox.prototype.onSelectionChange = function(oControlEvent) {
var oListItem = oControlEvent.getParameter("listItem"),
oNewSelectedItem = this._findMappedItem(oListItem),
sValue;
if ((oListItem.getType() === "Inactive") || // workaround: this is needed because the List fires the "selectionChange" event on inactive items
// a non editable or disabled ComboBox, the selection cannot be modified
!this.getEnabled() || !this.getEditable()) {
return;
}
// pre-assertion
jQuery.sap.assert(oNewSelectedItem, "The corresponding mapped item was not found on " + this);
if (oNewSelectedItem) {
// set the input value
this.updateDomValue(oNewSelectedItem.getText());
// update the selected item
this.setSelection(oNewSelectedItem, {
suppressInvalidate: true,
listItemUpdated: true
});
this.fireSelectionChange({ selectedItem: this.getSelectedItem() });
sValue = this.getValue();
if (sap.ui.Device.system.desktop) {
// deselect the text and move the text cursor at the endmost position (only ie)
jQuery.sap.delayedCall(0, this, "selectText", [sValue.length, sValue.length]);
}
}
};
/**
* Handle the item press event on the List.
*
* @param {sap.ui.base.Event} oControlEvent
* @private
*/
ComboBox.prototype.onItemPress = function() {
this.close();
};
/* ----------------------------------------------------------- */
/* Keyboard handling */
/* ----------------------------------------------------------- */
/**
* Handle the keydown event.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onkeydown = function(oEvent) {
ComboBoxBase.prototype.onkeydown.apply(this, arguments);
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
var mKeyCode = jQuery.sap.KeyCodes;
this._bDoTypeAhead = (oEvent.which !== mKeyCode.BACKSPACE) && (oEvent.which !== mKeyCode.DELETE);
};
/**
* Handle cut event.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.oncut = function(oEvent) {
ComboBoxBase.prototype.oncut.apply(this, arguments);
this._bDoTypeAhead = false;
};
/**
* Handle when enter is pressed.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onsapenter = function(oEvent) {
ComboBoxBase.prototype.onsapenter.apply(this, arguments);
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// a non editable or disabled ComboBox, the selection cannot be modified
if (!this.getEnabled() || !this.getEditable()) {
return;
}
var sValue = this.getValue();
this.setValue(sValue);
// no text selection
this.selectText(sValue.length, sValue.length);
if (this.isOpen()) {
this.close();
}
};
/**
* Handle when keyboard DOWN arrow is pressed.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onsapdown = function(oEvent) {
// a non editable or disabled ComboBox, the selection cannot be modified
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// note: prevent document scrolling when arrow keys are pressed
oEvent.preventDefault();
var oNextSelectableItem,
aSelectableItems = this.getSelectableItems();
oNextSelectableItem = aSelectableItems[aSelectableItems.indexOf(this.getSelectedItem()) + 1];
fnHandleKeyboardNavigation.call(this, oNextSelectableItem);
};
/**
* Handle when keyboard UP arrow is pressed.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onsapup = function(oEvent) {
// a non editable or disabled ComboBox, the selection cannot be modified
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// note: prevent document scrolling when arrow keys are pressed
oEvent.preventDefault();
var oPrevSelectableItem,
aSelectableItems = this.getSelectableItems();
oPrevSelectableItem = aSelectableItems[aSelectableItems.indexOf(this.getSelectedItem()) - 1];
fnHandleKeyboardNavigation.call(this, oPrevSelectableItem);
};
/**
* Handle Home key pressed.
* Select the first selectable item and update the input field accordingly.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onsaphome = function(oEvent) {
// a non editable or disabled ComboBox, the selection cannot be modified
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// note: prevent document scrolling when Home key is pressed
oEvent.preventDefault();
var oFirstSelectableItem = this.getSelectableItems()[0];
fnHandleKeyboardNavigation.call(this, oFirstSelectableItem);
};
/**
* Handle End key pressed.
* Select the last selectable item and update the input field accordingly.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onsapend = function(oEvent) {
// a non editable or disabled ComboBox, the selection cannot be modified
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// note: prevent document scrolling when End key is pressed
oEvent.preventDefault();
var oLastSelectableItem = this.findLastEnabledItem(this.getSelectableItems());
fnHandleKeyboardNavigation.call(this, oLastSelectableItem);
};
/**
* Handle when page down key is pressed.
*
* Select the last visible item. If the last visible item is already selected,
* scroll one page down and select the then last visible item.
* If the last item is selected, do nothing.
* Update the input field accordingly.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onsappagedown = function(oEvent) {
// non editable or disabled ComboBox, the selection cannot be modified
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// note: prevent document scrolling when page down key is pressed
oEvent.preventDefault();
var aSelectableItems = this.getSelectableItems(),
iIndex = aSelectableItems.indexOf(this.getSelectedItem()) + 10,
oItem;
// constrain the index
iIndex = (iIndex > aSelectableItems.length - 1) ? aSelectableItems.length - 1 : Math.max(0, iIndex);
oItem = aSelectableItems[iIndex];
fnHandleKeyboardNavigation.call(this, oItem);
};
/**
* Handle when page up key is pressed.
*
* Select the first visible item. If the first visible item is already selected,
* scroll one page up and select the then first visible item.
* If the first item is selected, do nothing.
* Update the input field accordingly.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onsappageup = function(oEvent) {
// a non editable or disabled ComboBox the selection cannot be modified
if (!this.getEnabled() || !this.getEditable()) {
return;
}
// mark the event for components that needs to know if the event was handled
oEvent.setMarked();
// note: prevent document scrolling when page up key is pressed
oEvent.preventDefault();
var aSelectableItems = this.getSelectableItems(),
iIndex = aSelectableItems.indexOf(this.getSelectedItem()) - 10,
oItem;
// constrain the index
iIndex = (iIndex > aSelectableItems.length - 1) ? aSelectableItems.length - 1 : Math.max(0, iIndex);
oItem = aSelectableItems[iIndex];
fnHandleKeyboardNavigation.call(this, oItem);
};
/**
* Handle the focusin event.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onfocusin = function(oEvent) {
this.$().addClass("sapMComboBoxFocused");
// the arrow is receiving focus
if (oEvent.target === this.getOpenArea()) {
// the value state message can not be opened if click on the open area
this.bCanNotOpenMessage = true;
// avoid the text-editing mode pop-up to be open on mobile,
// text-editing mode disturbs the usability experience (it blocks the UI in some devices)
// note: This occurs only in some specific mobile devices
if (sap.ui.Device.system.desktop) {
// force the focus to stay in the input field
this.focus();
}
// probably the input field is receiving focus
} else {
// avoid the text-editing mode pop-up to be open on mobile,
// text-editing mode disturbs the usability experience (it blocks the UI in some devices)
// note: This occurs only in some specific mobile devices
if (sap.ui.Device.system.desktop) {
jQuery.sap.delayedCall(0, this, function() {
if (document.activeElement === this.getFocusDomRef()) {
this.selectText(0, this.getValue().length);
}
});
}
// open the message pop-up
if (!this.isOpen() && !this.bCanNotOpenMessage) {
this.openValueStateMessage();
}
this.bCanNotOpenMessage = false;
}
};
/**
* Handle the focus leave event.
*
* @param {jQuery.Event} oEvent The event object.
* @private
*/
ComboBox.prototype.onsapfocusleave = function(oEvent) {
var oPicker = this.getAggregation("picker");
this.$().removeClass("sapMComboBoxFocused");
if (!oEvent.relatedControlId || !oPicker) {
return;
}
var oControl = sap.ui.getCore().byId(oEvent.relatedControlId),
oFocusDomRef = oControl && oControl.getFocusDomRef();
if (jQuery.sap.containsOrEquals(oPicker.getFocusDomRef(), oFocusDomRef)) {
if (sap.ui.Device.system.desktop) {
// force the focus to stay in the input field
this.focus();
}
}
};
/* =========================================================== */
/* API methods */
/* =========================================================== */
/* ----------------------------------------------------------- */
/* protected methods */
/* ----------------------------------------------------------- */
/*
* Update and synchronize "selectedItem" association, "selectedItemId", "selectedKey" properties and
* the "selectedItem" in the List.
*
* @param {sap.ui.core.Item | null} vItem
* @param {object} [mOptions]
* @param {boolean} [mOptions.suppressInvalidate]
* @param {boolean} [mOptions.listItemUpdated]
* @protected
*/
ComboBox.prototype.setSelection = function(vItem, mOptions) {
var oListItem,
oDomRef,
sActivedescendant = "aria-activedescendant";
mOptions = mOptions || {};
this.setAssociation("selectedItem", vItem || null, mOptions.suppressInvalidate);
this.setProperty("selectedItemId", (vItem instanceof sap.ui.core.Item) ? vItem.getId() : vItem, mOptions.suppressInvalidate);
if (typeof vItem === "string") {
vItem = sap.ui.getCore().byId(vItem);
}
this.setProperty("selectedKey", vItem ? vItem.getKey() : "", mOptions.suppressInvalidate);
oListItem = this.getListItem(vItem);
oDomRef = this.getFocusDomRef();
if (oDomRef) {
// the aria-activedescendant attribute is set when the list is rendered
if (vItem && oListItem && oListItem.getDomRef() && this.isOpen()) {
oDomRef.setAttribute(sActivedescendant, oListItem.getId());
} else {
oDomRef.removeAttribute(sActivedescendant);
}
}
// update the selection in the List
if (!mOptions.listItemUpdated) {
if (oListItem) {
// set the selected item of the List
this.getList().setSelectedItem(oListItem, true);
} else if (this.getList()) {
if (this.getDefaultSelectedItem()) {
this.getList().setSelectedItem(this.getListItem(this.getDefaultSelectedItem()), true);
} else if (this.getList().getSelectedItem()) {
this.getList().setSelectedItem(this.getList().getSelectedItem(), false);
}
}
}
};
/*
* Determines whether the "selectedItem" association and "selectedKey" property are synchronized.
*
* @returns {boolean}
* @protected
* @since 1.24.0
*/
ComboBox.prototype.isSelectionSynchronized = function() {
var vItem = this.getSelectedItem();
return this.getSelectedKey() === (vItem && vItem.getKey());
};
/**
* Synchronize selected item and key.
*
* @protected
*/
ComboBox.prototype.synchronizeSelection = function() {
// the "selectedKey" property is synchronized with the "selectedItem" association
if (this.isSelectionSynchronized()) {
return;
}
var sKey = this.getSelectedKey(),
vItem = this.getItemByKey("" + sKey); // find the first item with the given key
// if there is an item that match with the "selectedKey" property and
// the "selectedKey" property does not have the default value
if (vItem && (sKey !== "")) {
// update and synchronize "selectedItem" association and
// "selectedKey" property
this.setAssociation("selectedItem", vItem, true); // suppress re-rendering
this.setProperty("selectedItemId", vItem.getId(), true); // suppress re-rendering
// update the value if it has not changed
if (this._sValue === this.getValue()) {
this.setValue(vItem.getText());
}
}
};
/*
* Determines whether the list is filtered out from the input field.
*
* @returns {boolean} Whether the list is filtered out.
* @protected
* @since 1.26.0
*/
ComboBox.prototype.isFiltered = function() {
return this.getVisibleItems().length !== this.getItems().length;
};
/**
* 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
*/
ComboBox.prototype.createPicker = function(sPickerType) {
var oPicker = this.getAggregation("picker");
if (oPicker) {
return oPicker;
}
oPicker = this["_create" + sPickerType]();
// define a parent-child relationship between the control's and the picker pop-up
this.setAggregation("picker", oPicker, true);
// configuration
oPicker.setHorizontalScrolling(false)
.addStyleClass(sap.m.ComboBoxBaseRenderer.CSS_CLASS + "Picker")
.attachBeforeOpen(this.onBeforeOpen, this)
.attachAfterOpen(this.onAfterOpen, this)
.attachBeforeClose(this.onBeforeClose, this)
.attachAfterClose(this.onAfterClose, this)
.addEventDelegate({
onBeforeRendering: this.onBeforeRenderingPicker,
onAfterRendering: this.onAfterRenderingPicker
}, this)
.addContent(this.getList());
return oPicker;
};
/*
* Create an instance type of <code>sap.m.List</code>.
*
* @returns {sap.m.List}
* @protected
*/
ComboBox.prototype.createList = function() {
// list to use inside the picker
this._oList = new sap.m.List({
width: "100%",
mode: sap.m.ListMode.SingleSelectMaster,
rememberSelections: false // list should not remember selection
}).addStyleClass(sap.m.ComboBoxBaseRenderer.CSS_CLASS + "List")
.attachSelectionChange(this.onSelectionChange, this)
.attachItemPress(this.onItemPress, this);
};
/*
* This hook method is called before the control's picker pop-up is rendered.
*
* @protected
*/
ComboBox.prototype.onBeforeRenderingPicker = function() {
var fnOnBeforeRenderingPickerType = this["onBeforeRendering" + this.getPickerType()];
fnOnBeforeRenderingPickerType && fnOnBeforeRenderingPickerType.call(this);
};
/*
* This hook method is called after the control's picker pop-up is rendered.
*
* @protected
*/
ComboBox.prototype.onAfterRenderingPicker = function() {
var fnOnAfterRenderingPickerType = this["onAfterRendering" + this.getPickerType()];
fnOnAfterRenderingPickerType && fnOnAfterRenderingPickerType.call(this);
};
/*
* This event handler will be called before the control's picker pop-up is opened.
*
* @protected
*/
ComboBox.prototype.onBeforeOpen = function() {
var fnPickerTypeBeforeOpen = this["onBeforeOpen" + this.getPickerType()],
oDomRef = this.getFocusDomRef();
// add the active state to the control field
this.addStyleClass(sap.m.ComboBoxBaseRenderer.CSS_CLASS + "Pressed");
if (oDomRef) {
// expose a parent/child contextual relationship to assistive technologies
// note: the "aria-owns" attribute is set when the list is visible and in view
oDomRef.setAttribute("aria-owns", this.getList().getId());
}
// call the hook to add additional content to the List
this.addContent();
fnPickerTypeBeforeOpen && fnPickerTypeBeforeOpen.call(this);
};
/*
* This event handler will be called before the control's picker popover is opened.
*
* @protected
*/
ComboBox.prototype.onBeforeOpenPopover = function() {
var oDomRef = this.getDomRef();
if (oDomRef) {
this.getPicker().setContentWidth((oDomRef.offsetWidth / parseFloat(sap.m.BaseFontSize)) + "rem");
}
};
/*
* This event handler will be called after the control's picker pop-up is opened.
*
* @protected
*/
ComboBox.prototype.onAfterOpen = function() {
var oDomRef = this.getFocusDomRef(),
oListItem = this.getListItem(this.getSelectedItem());
if (oDomRef) {
oDomRef.setAttribute("aria-expanded", "true");
// note: the "aria-activedescendant" attribute is set when the currently active descendant is visible and in view
oListItem && oDomRef.setAttribute("aria-activedescendant", oListItem.getId());
}
};
/*
* This event handler will be called before the picker pop-up is closed.
*
* @protected
*/
ComboBox.prototype.onBeforeClose = function() {
var oDomRef = this.getFocusDomRef();
if (oDomRef) {
// note: the "aria-owns" attribute is removed when the list is not visible and in view
oDomRef.removeAttribute("aria-owns");
// the "aria-activedescendant" attribute is removed when the currently active descendant is not visible
oDomRef.removeAttribute("aria-activedescendant");
}
// remove the active state of the control's field
this.removeStyleClass(sap.m.ComboBoxBaseRenderer.CSS_CLASS + "Pressed");
};
/*
* This event handler will be called after the picker pop-up is closed.
*
* @protected
*/
ComboBox.prototype.onAfterClose = function() {
var oDomRef = this.getFocusDomRef();
if (oDomRef) {
oDomRef.setAttribute("aria-expanded", "false");
}
// if the focus is back to the input after close the picker, the message should be open
if (document.activeElement === oDomRef) {
this.openValueStateMessage();
}
// clear the filter to make all items visible
// note: to prevent flickering, the filter is cleared
// after the close animation is completed
this.clearFilter();
};
/*
* Check whether an item is selected or not.
*
* @param {sap.ui.core.Item} vItem
* @returns {boolean} Whether the item is selected.
* @protected
* @since 1.24.0
*/
ComboBox.prototype.isItemSelected = function(vItem) {
return vItem && (vItem.getId() === this.getAssociation("selectedItem"));
};
/**
* Retrieves the default selected item from the aggregation named <code>items</code>.
*
* @returns {null}
* @protected
*/
ComboBox.prototype.getDefaultSelectedItem = function() {
return null;
};
/*
* Clear the selection.
*
* @protected
*/
ComboBox.prototype.clearSelection = function() {
this.setSelection(null);
};
/**
* Sets the start and end positions of the current text selection.
*
* @param {integer} iSelectionStart The index into the text at which the first selected character is located.
* @param {integer} iSelectionEnd The index into the text at which the last selected character is located.
* @protected
* @since 1.22.1
*/
ComboBox.prototype.selectText = function(iSelectionStart, iSelectionEnd) {
ComboBoxBase.prototype.selectText.apply(this, arguments);
this.textSelectionStart = iSelectionStart;
this.textSelectionEnd = iSelectionEnd;
return this;
};
/* ----------------------------------------------------------- */
/* public methods */
/* ----------------------------------------------------------- */
/**
* Setter for association <code>selectedItem</code>.
*
* @param {string | sap.ui.core.Item | null} vItem new value for association <code>selectedItem</code>
* Id of an sap.ui.core.Item which becomes the new target of this <code>selectedItem</code> association.
* Alternatively, an sap.ui.core.Item instance may be given or null.
* If the value of null is provided the first enabled item will be selected (if any).
*
* @returns {sap.m.ComboBox} <code>this</code> to allow method chaining.
* @public
*/
ComboBox.prototype.setSelectedItem = function(vItem) {
if (typeof vItem === "string") {
vItem = sap.ui.getCore().byId(vItem);
}
if (!(vItem instanceof sap.ui.core.Item) && vItem !== null) {
jQuery.sap.log.warning('Warning: setSelectedItem() "vItem" has to be an instance of sap.ui.core.Item, a valid sap.ui.core.Item id, or null on', this);
return this;
}
if (!vItem) {
vItem = this.getDefaultSelectedItem();
}
// update and synchronize "selectedItem" association,
// "selectedKey" and "selectedItemId" properties
this.setSelection(vItem, { suppressInvalidate: true });
// set the input value
if (vItem) {
this.setValue(vItem.getText(), true);
/*eslint-disable no-cond-assign */
} else if (vItem = this.getDefaultSelectedItem()) {
/*eslint-enable no-cond-assign */
this.setValue(vItem.getText(), true);
} else {
this.setValue("", true);
}
return this;
};
/**
* Setter for property <code>selectedItemId</code>.
*
* Default value is an empty string <code>""</code> or <code>undefined</code>.
* If the provided <code>vItem</code> has a default value,
* the first enabled item will be selected (if any).
*
* @param {string | undefined} vItem New value for property <code>selectedItemId</code>.
* @returns {sap.m.ComboBox} <code>this</code> to allow method chaining.
* @public
*/
ComboBox.prototype.setSelectedItemId = function(vItem) {
vItem = this.validateProperty("selectedItemId", vItem);
if (!vItem) {
vItem = this.getDefaultSelectedItem();
}
// update and synchronize "selectedItem" association,
// "selectedKey" and "selectedItemId" properties
this.setSelection(vItem, { suppressInvalidate: true });
vItem = this.getSelectedItem();
// set the input value
if (vItem) {
this.setValue(vItem.getText(), true);
/*eslint-disable no-cond-assign */
} else if (vItem = this.getDefaultSelectedItem()) {
/*eslint-enable no-cond-assign */
this.setValue(vItem.getText(), true);
} else {
this.setValue("", true);
}
return this;
};
/**
* Setter for property <code>selectedKey</code>.
*
* Default value is an empty string <code>""</code> or <code>undefined</code>.
*
* If the provided <code>sKey</code> has a default value,
* the first enabled item will be selected (if any).
* In the case that an item has the default key value, it will be selected instead.
*
* @param {string} sKey New value for property <code>selectedKey</code>.
* @returns {sap.m.ComboBox} <code>this</code> to allow method chaining.
* @public
*/
ComboBox.prototype.setSelectedKey = function(sKey) {
sKey = this.validateProperty("selectedKey", sKey);
var oItem = this.getItemByKey(sKey);
if (oItem || (sKey === "")) {
// If the "sKey" value is an empty string "" or undefined,
// the first enabled item will be selected (if any).
// In the case that an item has the default key value, it will be selected instead.
if (!oItem && sKey === "") {
oItem = this.getDefaultSelectedItem();
}
// update and synchronize "selectedItem" association,
// "selectedKey" and "selectedItemId" properties
this.setSelection(oItem, { suppressInvalidate: true });
// set the input value
if (oItem) {
this.setValue(oItem.getText(), true);
/*eslint-disable no-cond-assign */
} else if (oItem = this.getDefaultSelectedItem()) {
/*eslint-enable no-cond-assign */
this.setValue(oItem.getText(), true);
} else {
this.setValue("", true);
}
return this;
}
// note: setSelectedKey() method sometimes is called
// before the items are added, in this case the "selectedItem" association,
// "selectedItemId" and the "value" properties need to be updated in onBeforeRendering()
this._sValue = this.getValue();
return this.setProperty("selectedKey", sKey); // update "selectedKey" property, re-rendering is needed
};
/**
* Retrieves the selected item object from the aggregation named <code>items</code>.
*
* @returns {sap.ui.core.Item | null} The current target of the <code>selectedItem</code> association, or null.
* @public
*/
ComboBox.prototype.getSelectedItem = function() {
var vSelectedItem = this.getAssociation("selectedItem");
return (vSelectedItem === null) ? null : sap.ui.getCore().byId(vSelectedItem) || null;
};
/**
* 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
*/
ComboBox.prototype.removeItem = function(vItem) {
vItem = ComboBoxBase.prototype.removeItem.call(this, vItem);
var sValue = this.getValue(),
oItem;
// no items, the removed item was the last
if (this.getItems().length === 0) {
// clear the selection
this.clearSelection();
} else if (this.isItemSelected(vItem)) { // if the removed item is selected
oItem = this.getDefaultSelectedItem();
this.setSelection(oItem);
this.setValue(sValue);
}
// return the removed item or null
return vItem;
};
return ComboBox;
}, /* bExport= */ true);