📄 comboboxitem.js
字号:
/*
* Isomorphic SmartClient
* Version 6.5 (2008-04-30)
* Copyright(c) 1998-2007 Isomorphic Software, Inc. All rights reserved.
* "SmartClient" is a trademark of Isomorphic Software, Inc.
*
* licensing@smartclient.com
*
* http://smartclient.com/license
*/
//> @class ComboBoxItem// The Combobox is a text input field which can show a list of options via a drop-down// PickList.// <p>// The set of options will be filtered based on the current value in the text field, so only// options that match what has been typed so far will be displayed.// The set of options can be derived from a ValueMap or dynamically retrieved from a// dataSource. See the +link{interface:PickList} interface for further settings.// <P>// Note that to select the first option as a default value for the item,// +link{ComboBoxItem.defaultToFirstOption} may be set.//// @see interface:PickList// @implements PickList// @treeLocation Client Reference/Forms/Form Items// @example listComboBox // @visibility comboBox// @example listComboBox//<// Example of a Combo-Box type item in Windows applications: The URL bar for most browsers.// ComboBox is used for:// - "search": ComboBox is in a search form which is bound to the DataSource being searched// - eg: autoCompletion on names in an address book// - "find-related": ComboBox is in an editing form and is being used to pick related records// from other DataSources// - eg: when editing an Account, find a User record to use as account.owner// - in this case, we want to// - default to displaying identifying fields from the related records// - store the primary key of the related record, NOTE however:// - the fieldName in the record being edited may not be the same as the fieldName// of the PK in the related record// - we may not actually store the PK if field.foreignKey indicates some other field.// Eg, the primaryKey might be a meaningless internal value and we may store instead// some other unique valueisc.defineClass("ComboBoxItem", "TextItem", "PickList").addMethods({ //>@attr ComboBoxItem.defaultValue (boolean : null : IRW) // Static default value for this ComboBoxItem. To default to the first option use // +link{ComboBoxItem.defaultToFirstOption} instead. // @visibility external //< //> @method ComboBoxItem.defaultDynamicValue() (A) // Expression evaluated to determine the +link{ComboBoxItem.defaultValue} when no value is // provided for this item. To default to the first option use // +link{ComboBoxItem.defaultToFirstOption} instead. // @visibility external //< //> @attr ComboBoxItem.defaultToFirstOption (boolean : false : IRW) // Select the first option as the default value for this ComboBoxItem. If options are derived // from a dataSource, the first value returned by the server will be used, otherwise the first // value in the valueMap. If enabled, this setting overrides +link{ComboBoxItem.defaultValue} // and +link{ComboBoxItem.defaultDynamicValue}|. // @visibility external //< // Default to auto-sizing pickList // This means the pickList will expand to the size required to accomodate its content. // As the user types and filters occur, this means the pickList may resize horizontally but // seems to have no obvious performance impact autoSizePickList:true, // Override drawn() - if this is a databound pickList we want to perform a filter before // the pickList itself ever gets shown. drawn : function (a,b,c,d) { this.invokeSuper(isc.ComboBoxItem, "drawn", a,b,c,d); if (this.autoFetchData && this._getOptionsFromDataSource()) { this.filterWithValue = false; this.fetchData(null, null, true); } }, //>@attr ComboBoxItem.showPickerIcon (boolean : true : [IRWA]) // Show the picker icon for the combo box // @visibility external //< showPickerIcon:true, //>@attr ComboBoxItem.pickerIconWidth (number : 15 : [IRW]) // Default the picker icon to a fixed with (15px). // @visibility external //< pickerIconWidth:15, //>@attr ComboBoxItem.pickerIconHeight (number : null : [IRW]) // Don't specify an explicit height for the picker icon - instead have it size to match the // height of the combo box item. // @visibility external //< //>@attr ComboBoxItem.pickerIconSrc (SCImgURL : "[SKIN]/DynamicForm/ComboBoxItem_PickButton_icon.gif" : [IRWA]) // Src for the picker icon // @visibility external //< pickerIconSrc:"[SKIN]/DynamicForm/ComboBoxItem_PickButton_icon.gif", // Apply some default properties to the picker icon. pickerIconProperties:{ // We don't want it to be imgOnly because we need click handling, but we don't want it // in the page's tab order tabIndex:-1, showOver:true }, // override modalPickList - we don't want to take focus from the text item when the // pickList is shown. modalPickList:false, //>@attr ComboBoxItem.showPickListOnKeypress (boolean : true : IRW) // Should the list of options be displayed whenever the user types into the // the combo-box textArea, or only when the user clicks on the pick button or uses the // explicit <code>Alt+Arrow Down</code> key combo? // @visibility comboBox //< showPickListOnKeypress:true, //>@attr ComboBoxItem.completeOnTab (boolean : null : IRW) // If true, when the pickList is showing, the user can select the current value by hitting // the <code>Tab</code> key. // @visibility comboBox //< //completeOnTab:null, // Implement pickListShown to set up a page level mousedown handler to hide the pickList. pickListShown : function () { if (this.pickList.isVisible()) { // Don't pass in the 'fire once' param - if the user clicks outside we'll clear the // click event in response to that click. If the user clicks on the pickList // (or it's scrollbar, for example) we want to continue listening for future clicks // outside. this._pageClickID = this.ns.Page.setEvent("mouseDown", this, null, "_clickOutside"); } }, // If the user clicks on the page while the pickList is up, hide the pickList _clickOutside : function () { var pl = this.pickList; if (!pl || !pl.isVisible()) return; var target = isc.EH.lastEvent.target; if (!pl.contains(target, true)) pl.hide(); // If the click occurred over the pickerIcon we don't want to re-show in response to // the click that follows this mouseDown. // If the click occurred over the PickList, (or its scrollbar), in IE native focus will // be taken from the textbox, even though the scrollbar is non-focusable. // Restore focus on mouse up so the user can continue typing / do arrow-key navigation // from the textbox. this._dismissOnMouseUp = this.ns.Page.setEvent("mouseUp", this, isc.Page.FIRE_ONCE, "_dismissPickListClick"); // Note: if the user is dragging the scrollbar, we'll see a dragStop event, with no // mouseUp this._refocusOnDragStop = this.ns.Page.setEvent("dragStop", this, isc.Page.FIRE_ONCE, "_refocusFromPLMouseUp"); }, _dismissPickListClick : function () { // If the click happened over this item, cancel it. this will prevent the // pickList from showing when it was hidden on a mousedown and the user clicks this item. if (this.form._getEventTargetItemInfo().item == this) return false; this._refocusFromPLMouseUp(true); }, _refocusFromPLMouseUp : function (fromClick) { if (fromClick == true) { this.ns.Page.clearEvent("dragStop", this._refocusOnDragStop); } else { this.ns.Page.clearEvent("mouseUp", this._dismissPickListClick); } delete this._refocusOnDragStop; delete this._dismissPickListClick; if (this.pickList && this.pickList.isVisible() && this.pickList.contains(isc.EH.getTarget())) { this.focusInItem(); } }, // Implement pickListHidden to clear the page level click event to hide the pickList, if // we haven't already. pickListHidden : function () { if (this._pageClickID) this.ns.Page.clearEvent("mouseDown", this._pageClickID); delete this._pageClickID; }, // Override handkeKeyPress - as the user types, we want to re-filter the list. // Also proxy Arrow key presses to the PickList to navigate through options. // Behavior: // - We don't want the list showing if // - there are no matches // - the textItem is empty // - Otherwise we want the list to show. _$ArrowUp:"Arrow_Up", _$ArrowDown:"Arrow_Down", _$PageUp:"Page_Up", _$PageDown:"Page_Down", _$Escape:"Escape", _$Enter:"Enter", _$Tab:"Tab", handleKeyPress : function () { if (!this.hasFocus) return this.Super("handleKeyPress", arguments); var keyName = isc.EH.lastEvent.keyName, pickList = this.pickList, pickListVisible = (pickList ? (pickList.isDrawn() && pickList.isVisible()) : false); // deliver PageUp/Down to the body to cause scrolling if (pickListVisible && (keyName == this._$PageDown || keyName == this._$PageUp)) { return pickList.body.handleKeyPress(isc.EH.lastEvent); } var value = this.getValue(), isEmpty = (!value || value == isc.emptyString); if (keyName == this._$ArrowDown && isc.EH.altKeyDown()) { // By default we hide the picklist whenever we get a keypress and the value is // empty (this is for the case where the user clears out the combobox text value). // Set a flag here to avoid hiding the combobox unless the value has subsequently // changed. if (isEmpty) this._shownOnEmpty = true; this.filterWithValue = false; this.showPickList(); return false; } if (pickListVisible) { // pass navigation keys (arrows) through to the drop-down list // so the user can navigate through the selection if (keyName == this._$ArrowDown || keyName == this._$ArrowUp || // also pass "Enter" up to the list to trigger 'itemClick' behavior // and "Escape" to trigger 'cancel' behavior keyName == this._$Enter || keyName == this._$Escape) { pickList.bodyKeyPress(isc.EH.lastEvent); // kill the native behavior - shifting the cursor in the text field return false; } // If completeOnTab is true, pick the currently selected value on tab. // Also do so if autoComplete:"smart" is enabled (inline autoCompletion), // as tab accepts an inline completion. if (pickList && pickList.isVisible() && keyName == this._$Tab && (this.completeOnTab || this._getAutoCompleteSetting() == this._$smart)) { var selection = pickList.getSelectedRecord(); if (selection != null) pickList.itemClick(selection); } } return this.Super("handleKeyPress", arguments); }, // Override handleChange to re filter the list on every change (which occurs on every // keypress) handleChange : function (newValue, oldValue) { var returnVal = this.Super("handleChange", arguments); if (returnVal == false) return false; // Check for the change handler having modified the value to be saved. newValue = this._changeValue; var isEmpty = (!newValue || newValue == isc.emptyString); // clear out the shownOnEmpty string if we're not empty any more if (!isEmpty) delete this._shownOnEmpty; // if the text field is empty, ensure the list is hidden var pickList = this.pickList, pickListVisible = (pickList ? pickList.isVisible() : false); if (isEmpty && !this._shownOnEmpty) { if (pickListVisible) pickList.hide(); } else if (this.showPickListOnKeypress || pickListVisible) { // At this point we know the change is ok, but the new value has not yet been saved // Save the value out so our filter will work this.saveValue(newValue); // showPickList will set up the pickList initially, or if already set up // will re-filter // Note - if our value changed in response to the user picking something from the // list we don't want to show the pickList again. // Note - pass in the second 'queueFetches' parameter - we don't want to kick off // multiple server fetches while the user is rapidly typing in the text field if (!this._valuePicked && this.hasFocus) { this.filterWithValue = true; this.showPickList(true, true); } } }, // Override selectDefaultItem to always select the first item in the list. // This will happen on every re-filter. selectDefaultItem : function () { if (this.pickList == null || this.pickList.destroyed) return; var selection = this.pickList.selection; // If there's already something selected, just bail - we only want to select the first // item when the filter changes (and the old selection gets dropped). if (this.pickList.selection.anySelected()) return; var record = this.pickList.getRecord(0); // Don't attempt to select null / loading / separator rows if (record == null || Array.isLoading(record) || record[this.pickList.isSeparatorProperty]) return; selection.selectSingle(record); // Clear last hilite - required so keyboard navigatioin will pick up the current position // from the selection, not the last hilite position. this.pickList.clearLastHilite(); this.pickList.scrollRecordIntoView(0); }, // ------------------------ // Filtering data // ------------------------ // Include useful JSDoc from pickList
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -