1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
- <style type="text/css">
- .highlight { display: block; background-color: #ddd; }
- </style>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-form-field-ComboBox'>/**
- </span> * @docauthor Jason Johnston <jason@sencha.com>
- *
- * A combobox control with support for autocomplete, remote loading, and many other features.
- *
- * A ComboBox is like a combination of a traditional HTML text `<input>` field and a `<select>`
- * field; the user is able to type freely into the field, and/or pick values from a dropdown selection
- * list. The user can input any value by default, even if it does not appear in the selection list;
- * to prevent free-form values and restrict them to items in the list, set {@link #forceSelection} to `true`.
- *
- * The selection list's options are populated from any {@link Ext.data.Store}, including remote
- * stores. The data items in the store are mapped to each option's displayed text and backing value via
- * the {@link #valueField} and {@link #displayField} configurations, respectively.
- *
- * If your store is not remote, i.e. it depends only on local data and is loaded up front, you should be
- * sure to set the {@link #queryMode} to `'local'`, as this will improve responsiveness for the user.
- *
- * # Example usage:
- *
- * @example
- * // The data store containing the list of states
- * var states = Ext.create('Ext.data.Store', {
- * fields: ['abbr', 'name'],
- * data : [
- * {"abbr":"AL", "name":"Alabama"},
- * {"abbr":"AK", "name":"Alaska"},
- * {"abbr":"AZ", "name":"Arizona"}
- * //...
- * ]
- * });
- *
- * // Create the combo box, attached to the states data store
- * Ext.create('Ext.form.ComboBox', {
- * fieldLabel: 'Choose State',
- * store: states,
- * queryMode: 'local',
- * displayField: 'name',
- * valueField: 'abbr',
- * renderTo: Ext.getBody()
- * });
- *
- * # Events
- *
- * To do something when something in ComboBox is selected, configure the select event:
- *
- * var cb = Ext.create('Ext.form.ComboBox', {
- * // all of your config options
- * listeners:{
- * scope: yourScope,
- * 'select': yourFunction
- * }
- * });
- *
- * // Alternatively, you can assign events after the object is created:
- * var cb = new Ext.form.field.ComboBox(yourOptions);
- * cb.on('select', yourFunction, yourScope);
- *
- * # Multiple Selection
- *
- * ComboBox also allows selection of multiple items from the list; to enable multi-selection set the
- * {@link #multiSelect} config to `true`.
- *
- * # Filtered Stores
- *
- * If you have a local store that is already filtered, you can use the {@link #lastQuery} config option
- * to prevent the store from having the filter being cleared on first expand.
- *
- * ## Customized combobox
- *
- * Both the text shown in dropdown menu and text field can be easily customized:
- *
- * @example
- * var states = Ext.create('Ext.data.Store', {
- * fields: ['abbr', 'name'],
- * data : [
- * {"abbr":"AL", "name":"Alabama"},
- * {"abbr":"AK", "name":"Alaska"},
- * {"abbr":"AZ", "name":"Arizona"}
- * ]
- * });
- *
- * Ext.create('Ext.form.ComboBox', {
- * fieldLabel: 'Choose State',
- * store: states,
- * queryMode: 'local',
- * valueField: 'abbr',
- * renderTo: Ext.getBody(),
- * // Template for the dropdown menu.
- * // Note the use of "x-boundlist-item" class,
- * // this is required to make the items selectable.
- * tpl: Ext.create('Ext.XTemplate',
- * '<tpl for=".">',
- * '<div class="x-boundlist-item">{abbr} - {name}</div>',
- * '</tpl>'
- * ),
- * // template for the content inside text field
- * displayTpl: Ext.create('Ext.XTemplate',
- * '<tpl for=".">',
- * '{abbr} - {name}',
- * '</tpl>'
- * )
- * });
- *
- * See also the {@link #listConfig} option for additional configuration of the dropdown.
- *
- */
- Ext.define('Ext.form.field.ComboBox', {
- extend:'Ext.form.field.Picker',
- requires: ['Ext.util.DelayedTask', 'Ext.EventObject', 'Ext.view.BoundList', 'Ext.view.BoundListKeyNav', 'Ext.data.StoreManager', 'Ext.layout.component.field.ComboBox'],
- alternateClassName: 'Ext.form.ComboBox',
- alias: ['widget.combobox', 'widget.combo'],
- mixins: {
- bindable: 'Ext.util.Bindable'
- },
- componentLayout: 'combobox',
- <span id='Ext-form-field-ComboBox-cfg-triggerCls'> /**
- </span> * @cfg {String} [triggerCls='x-form-arrow-trigger']
- * An additional CSS class used to style the trigger button. The trigger will always get the {@link #triggerBaseCls}
- * by default and `triggerCls` will be **appended** if specified.
- */
- triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
-
- <span id='Ext-form-field-ComboBox-cfg-hiddenName'> /**
- </span> * @cfg {String} [hiddenName=""]
- * The name of an underlying hidden field which will be synchronized with the underlying value of the combo.
- * This option is useful if the combo is part of a form element doing a regular form post. The hidden field
- * will not be created unless a hiddenName is specified.
- */
- hiddenName: '',
-
- <span id='Ext-form-field-ComboBox-property-hiddenDataEl'> /**
- </span> * @property {Ext.Element} hiddenDataEl
- * @private
- */
- <span id='Ext-form-field-ComboBox-cfg-hiddenDataCls'> /**
- </span> * @private
- * @cfg {String}
- * CSS class used to find the {@link #hiddenDataEl}
- */
- hiddenDataCls: Ext.baseCSSPrefix + 'hide-display ' + Ext.baseCSSPrefix + 'form-data-hidden',
- <span id='Ext-form-field-ComboBox-cfg-fieldSubTpl'> /**
- </span> * @cfg
- * @inheritdoc
- */
- fieldSubTpl: [
- '<div class="{hiddenDataCls}" role="presentation"></div>',
- '<input id="{id}" type="{type}" {inputAttrTpl} class="{fieldCls} {typeCls}" autocomplete="off"',
- '<tpl if="value"> value="{[Ext.util.Format.htmlEncode(values.value)]}"</tpl>',
- '<tpl if="name"> name="{name}"</tpl>',
- '<tpl if="placeholder"> placeholder="{placeholder}"</tpl>',
- '<tpl if="size"> size="{size}"</tpl>',
- '<tpl if="maxLength !== undefined"> maxlength="{maxLength}"</tpl>',
- '<tpl if="readOnly"> readonly="readonly"</tpl>',
- '<tpl if="disabled"> disabled="disabled"</tpl>',
- '<tpl if="tabIdx"> tabIndex="{tabIdx}"</tpl>',
- '<tpl if="fieldStyle"> style="{fieldStyle}"</tpl>',
- '/>',
- {
- compiled: true,
- disableFormats: true
- }
- ],
- getSubTplData: function(){
- var me = this;
- Ext.applyIf(me.subTplData, {
- hiddenDataCls: me.hiddenDataCls
- });
- return me.callParent(arguments);
- },
- afterRender: function(){
- var me = this;
- me.callParent(arguments);
- me.setHiddenValue(me.value);
- },
- <span id='Ext-form-field-ComboBox-cfg-store'> /**
- </span> * @cfg {Ext.data.Store/Array} store
- * The data source to which this combo is bound. Acceptable values for this property are:
- *
- * - **any {@link Ext.data.Store Store} subclass**
- * - **an Array** : Arrays will be converted to a {@link Ext.data.Store} internally, automatically generating
- * {@link Ext.data.Field#name field names} to work with all data components.
- *
- * - **1-dimensional array** : (e.g., `['Foo','Bar']`)
- *
- * A 1-dimensional array will automatically be expanded (each array item will be used for both the combo
- * {@link #valueField} and {@link #displayField})
- *
- * - **2-dimensional array** : (e.g., `[['f','Foo'],['b','Bar']]`)
- *
- * For a multi-dimensional array, the value in index 0 of each item will be assumed to be the combo
- * {@link #valueField}, while the value at index 1 is assumed to be the combo {@link #displayField}.
- *
- * See also {@link #queryMode}.
- */
- <span id='Ext-form-field-ComboBox-cfg-multiSelect'> /**
- </span> * @cfg {Boolean} multiSelect
- * If set to `true`, allows the combo field to hold more than one value at a time, and allows selecting multiple
- * items from the dropdown list. The combo's text field will show all selected values separated by the
- * {@link #delimiter}.
- */
- multiSelect: false,
- //<locale>
- <span id='Ext-form-field-ComboBox-cfg-delimiter'> /**
- </span> * @cfg {String} delimiter
- * The character(s) used to separate the {@link #displayField display values} of multiple selected items when
- * `{@link #multiSelect} = true`.
- */
- delimiter: ', ',
- //</locale>
- <span id='Ext-form-field-ComboBox-cfg-displayField'> /**
- </span> * @cfg {String} displayField
- * The underlying {@link Ext.data.Field#name data field name} to bind to this ComboBox.
- *
- * See also `{@link #valueField}`.
- */
- displayField: 'text',
- <span id='Ext-form-field-ComboBox-cfg-valueField'> /**
- </span> * @cfg {String} valueField (required)
- * The underlying {@link Ext.data.Field#name data value name} to bind to this ComboBox.
- *
- * **Note**: use of a `valueField` requires the user to make a selection in order for a value to be mapped. See also
- * `{@link #displayField}`.
- *
- * Defaults to match the value of the {@link #displayField} config.
- */
- <span id='Ext-form-field-ComboBox-cfg-triggerAction'> /**
- </span> * @cfg {String} triggerAction
- * The action to execute when the trigger is clicked.
- *
- * - **`'all'`** :
- *
- * {@link #doQuery run the query} specified by the `{@link #allQuery}` config option
- *
- * - **`'query'`** :
- *
- * {@link #doQuery run the query} using the {@link Ext.form.field.Base#getRawValue raw value}.
- *
- * See also `{@link #queryParam}`.
- */
- triggerAction: 'all',
- <span id='Ext-form-field-ComboBox-cfg-allQuery'> /**
- </span> * @cfg {String} allQuery
- * The text query to send to the server to return all records for the list with no filtering
- */
- allQuery: '',
- <span id='Ext-form-field-ComboBox-cfg-queryParam'> /**
- </span> * @cfg {String} queryParam
- * Name of the parameter used by the Store to pass the typed string when the ComboBox is configured with
- * `{@link #queryMode}: 'remote'`. If explicitly set to a falsy value it will not be sent.
- */
- queryParam: 'query',
- <span id='Ext-form-field-ComboBox-cfg-queryMode'> /**
- </span> * @cfg {String} queryMode
- * The mode in which the ComboBox uses the configured Store. Acceptable values are:
- *
- * - **`'remote'`** :
- *
- * In `queryMode: 'remote'`, the ComboBox loads its Store dynamically based upon user interaction.
- *
- * This is typically used for "autocomplete" type inputs, and after the user finishes typing, the Store is {@link
- * Ext.data.Store#method-load load}ed.
- *
- * A parameter containing the typed string is sent in the load request. The default parameter name for the input
- * string is `query`, but this can be configured using the {@link #queryParam} config.
- *
- * In `queryMode: 'remote'`, the Store may be configured with `{@link Ext.data.Store#remoteFilter remoteFilter}:
- * true`, and further filters may be _programatically_ added to the Store which are then passed with every load
- * request which allows the server to further refine the returned dataset.
- *
- * Typically, in an autocomplete situation, {@link #hideTrigger} is configured `true` because it has no meaning for
- * autocomplete.
- *
- * - **`'local'`** :
- *
- * ComboBox loads local data
- *
- * var combo = new Ext.form.field.ComboBox({
- * renderTo: document.body,
- * queryMode: 'local',
- * store: new Ext.data.ArrayStore({
- * id: 0,
- * fields: [
- * 'myId', // numeric value is the key
- * 'displayText'
- * ],
- * data: [[1, 'item1'], [2, 'item2']] // data is local
- * }),
- * valueField: 'myId',
- * displayField: 'displayText',
- * triggerAction: 'all'
- * });
- */
- queryMode: 'remote',
- <span id='Ext-form-field-ComboBox-cfg-queryCaching'> /**
- </span> * @cfg {Boolean} [queryCaching=true]
- * When true, this prevents the combo from re-querying (either locally or remotely) when the current query
- * is the same as the previous query.
- */
- queryCaching: true,
- <span id='Ext-form-field-ComboBox-cfg-pageSize'> /**
- </span> * @cfg {Number} pageSize
- * If greater than `0`, a {@link Ext.toolbar.Paging} is displayed in the footer of the dropdown list and the
- * {@link #doQuery filter queries} will execute with page start and {@link Ext.view.BoundList#pageSize limit}
- * parameters. Only applies when `{@link #queryMode} = 'remote'`.
- */
- pageSize: 0,
- <span id='Ext-form-field-ComboBox-cfg-queryDelay'> /**
- </span> * @cfg {Number} queryDelay
- * The length of time in milliseconds to delay between the start of typing and sending the query to filter the
- * dropdown list.
- *
- * Defaults to `500` if `{@link #queryMode} = 'remote'` or `10` if `{@link #queryMode} = 'local'`
- */
- <span id='Ext-form-field-ComboBox-cfg-minChars'> /**
- </span> * @cfg {Number} minChars
- * The minimum number of characters the user must type before autocomplete and {@link #typeAhead} activate.
- *
- * Defaults to `4` if `{@link #queryMode} = 'remote'` or `0` if `{@link #queryMode} = 'local'`,
- * does not apply if `{@link Ext.form.field.Trigger#editable editable} = false`.
- */
- <span id='Ext-form-field-ComboBox-cfg-autoSelect'> /**
- </span> * @cfg {Boolean} autoSelect
- * `true` to automatically highlight the first result gathered by the data store in the dropdown list when it is
- * opened. A false value would cause nothing in the list to be highlighted automatically, so
- * the user would have to manually highlight an item before pressing the enter or {@link #selectOnTab tab} key to
- * select it (unless the value of ({@link #typeAhead}) were true), or use the mouse to select a value.
- */
- autoSelect: true,
- <span id='Ext-form-field-ComboBox-cfg-typeAhead'> /**
- </span> * @cfg {Boolean} typeAhead
- * `true` to populate and autoselect the remainder of the text being typed after a configurable delay
- * ({@link #typeAheadDelay}) if it matches a known value.
- */
- typeAhead: false,
- <span id='Ext-form-field-ComboBox-cfg-typeAheadDelay'> /**
- </span> * @cfg {Number} typeAheadDelay
- * The length of time in milliseconds to wait until the typeahead text is displayed if `{@link #typeAhead} = true`
- */
- typeAheadDelay: 250,
- <span id='Ext-form-field-ComboBox-cfg-selectOnTab'> /**
- </span> * @cfg {Boolean} selectOnTab
- * Whether the Tab key should select the currently highlighted item.
- */
- selectOnTab: true,
- <span id='Ext-form-field-ComboBox-cfg-forceSelection'> /**
- </span> * @cfg {Boolean} forceSelection
- * `true` to restrict the selected value to one of the values in the list, `false` to allow the user to set
- * arbitrary text into the field.
- */
- forceSelection: false,
- <span id='Ext-form-field-ComboBox-cfg-growToLongestValue'> /**
- </span> * @cfg {Boolean} growToLongestValue
- * `false` to not allow the component to resize itself when its data changes
- * (and its {@link #grow} property is `true`)
- */
- growToLongestValue: true,
- <span id='Ext-form-field-ComboBox-cfg-valueNotFoundText'> /**
- </span> * @cfg {String} valueNotFoundText
- * When using a name/value combo, if the value passed to setValue is not found in the store, valueNotFoundText will
- * be displayed as the field text if defined. If this default text is used, it means there
- * is no value set and no validation will occur on this field.
- */
- <span id='Ext-form-field-ComboBox-property-lastQuery'> /**
- </span> * @property {String} lastQuery
- * The value of the match string used to filter the store. Delete this property to force a requery. Example use:
- *
- * var combo = new Ext.form.field.ComboBox({
- * ...
- * queryMode: 'remote',
- * listeners: {
- * // delete the previous query in the beforequery event or set
- * // combo.lastQuery = null (this will reload the store the next time it expands)
- * beforequery: function(qe){
- * delete qe.combo.lastQuery;
- * }
- * }
- * });
- *
- * To make sure the filter in the store is not cleared the first time the ComboBox trigger is used configure the
- * combo with `lastQuery=''`. Example use:
- *
- * var combo = new Ext.form.field.ComboBox({
- * ...
- * queryMode: 'local',
- * triggerAction: 'all',
- * lastQuery: ''
- * });
- */
- <span id='Ext-form-field-ComboBox-cfg-defaultListConfig'> /**
- </span> * @cfg {Object} defaultListConfig
- * Set of options that will be used as defaults for the user-configured {@link #listConfig} object.
- */
- defaultListConfig: {
- loadingHeight: 70,
- minWidth: 70,
- maxHeight: 300,
- shadow: 'sides'
- },
- <span id='Ext-form-field-ComboBox-cfg-transform'> /**
- </span> * @cfg {String/HTMLElement/Ext.Element} transform
- * The id, DOM node or {@link Ext.Element} of an existing HTML `<select>` element to convert into a ComboBox. The
- * target select's options will be used to build the options in the ComboBox dropdown; a configured {@link #store}
- * will take precedence over this.
- */
- <span id='Ext-form-field-ComboBox-cfg-listConfig'> /**
- </span> * @cfg {Object} listConfig
- * An optional set of configuration properties that will be passed to the {@link Ext.view.BoundList}'s constructor.
- * Any configuration that is valid for BoundList can be included. Some of the more useful ones are:
- *
- * - {@link Ext.view.BoundList#cls cls} - defaults to empty
- * - {@link Ext.view.BoundList#emptyText emptyText} - defaults to empty string
- * - {@link Ext.view.BoundList#itemSelector itemSelector} - defaults to the value defined in BoundList
- * - {@link Ext.view.BoundList#loadingText loadingText} - defaults to `'Loading...'`
- * - {@link Ext.view.BoundList#minWidth minWidth} - defaults to `70`
- * - {@link Ext.view.BoundList#maxWidth maxWidth} - defaults to `undefined`
- * - {@link Ext.view.BoundList#maxHeight maxHeight} - defaults to `300`
- * - {@link Ext.view.BoundList#resizable resizable} - defaults to `false`
- * - {@link Ext.view.BoundList#shadow shadow} - defaults to `'sides'`
- * - {@link Ext.view.BoundList#width width} - defaults to `undefined` (automatically set to the width of the ComboBox
- * field if {@link #matchFieldWidth} is true)
- */
- //private
- ignoreSelection: 0,
- //private, tells the layout to recalculate its startingWidth when a record is removed from its bound store
- removingRecords: null,
- //private helper
- resizeComboToGrow: function () {
- var me = this;
- return me.grow && me.growToLongestValue;
- },
- initComponent: function() {
- var me = this,
- isDefined = Ext.isDefined,
- store = me.store,
- transform = me.transform,
- transformSelect, isLocalMode;
- Ext.applyIf(me.renderSelectors, {
- hiddenDataEl: '.' + me.hiddenDataCls.split(' ').join('.')
- });
-
- //<debug>
- if (me.typeAhead && me.multiSelect) {
- Ext.Error.raise('typeAhead and multiSelect are mutually exclusive options -- please remove one of them.');
- }
- if (me.typeAhead && !me.editable) {
- Ext.Error.raise('If typeAhead is enabled the combo must be editable: true -- please change one of those settings.');
- }
- if (me.selectOnFocus && !me.editable) {
- Ext.Error.raise('If selectOnFocus is enabled the combo must be editable: true -- please change one of those settings.');
- }
- //</debug>
- this.addEvents(
- <span id='Ext-form-field-ComboBox-event-beforequery'> /**
- </span> * @event beforequery
- * Fires before all queries are processed. Return false to cancel the query or set the queryEvent's cancel
- * property to true.
- *
- * @param {Object} queryEvent An object that has these properties:
- *
- * - `combo` : Ext.form.field.ComboBox
- *
- * This combo box
- *
- * - `query` : String
- *
- * The query string
- *
- * - `forceAll` : Boolean
- *
- * True to force "all" query
- *
- * - `cancel` : Boolean
- *
- * Set to true to cancel the query
- */
- 'beforequery',
- <span id='Ext-form-field-ComboBox-event-select'> /**
- </span> * @event select
- * Fires when at least one list item is selected.
- * @param {Ext.form.field.ComboBox} combo This combo box
- * @param {Array} records The selected records
- */
- 'select',
- <span id='Ext-form-field-ComboBox-event-beforeselect'> /**
- </span> * @event beforeselect
- * Fires before the selected item is added to the collection
- * @param {Ext.form.field.ComboBox} combo This combo box
- * @param {Ext.data.Record} record The selected record
- * @param {Number} index The index of the selected record
- */
- 'beforeselect',
- <span id='Ext-form-field-ComboBox-event-beforedeselect'> /**
- </span> * @event beforedeselect
- * Fires before the deselected item is removed from the collection
- * @param {Ext.form.field.ComboBox} combo This combo box
- * @param {Ext.data.Record} record The deselected record
- * @param {Number} index The index of the deselected record
- */
- 'beforedeselect'
- );
- // Build store from 'transform' HTML select element's options
- if (transform) {
- transformSelect = Ext.getDom(transform);
- if (transformSelect) {
- if (!me.store) {
- store = Ext.Array.map(Ext.Array.from(transformSelect.options), function(option){
- return [option.value, option.text];
- });
- }
- if (!me.name) {
- me.name = transformSelect.name;
- }
- if (!('value' in me)) {
- me.value = transformSelect.value;
- }
- }
- }
- me.bindStore(store || 'ext-empty-store', true);
- store = me.store;
- if (store.autoCreated) {
- me.queryMode = 'local';
- me.valueField = me.displayField = 'field1';
- if (!store.expanded) {
- me.displayField = 'field2';
- }
- }
- if (!isDefined(me.valueField)) {
- me.valueField = me.displayField;
- }
- isLocalMode = me.queryMode === 'local';
- if (!isDefined(me.queryDelay)) {
- me.queryDelay = isLocalMode ? 10 : 500;
- }
- if (!isDefined(me.minChars)) {
- me.minChars = isLocalMode ? 0 : 4;
- }
- if (!me.displayTpl) {
- me.displayTpl = new Ext.XTemplate(
- '<tpl for=".">' +
- '{[typeof values === "string" ? values : values["' + me.displayField + '"]]}' +
- '<tpl if="xindex < xcount">' + me.delimiter + '</tpl>' +
- '</tpl>'
- );
- } else if (Ext.isString(me.displayTpl)) {
- me.displayTpl = new Ext.XTemplate(me.displayTpl);
- }
- me.callParent();
- me.doQueryTask = new Ext.util.DelayedTask(me.doRawQuery, me);
- // store has already been loaded, setValue
- if (me.store.getCount() > 0) {
- me.setValue(me.value);
- }
- // render in place of 'transform' select
- if (transformSelect) {
- me.render(transformSelect.parentNode, transformSelect);
- Ext.removeNode(transformSelect);
- delete me.renderTo;
- }
- },
- <span id='Ext-form-field-ComboBox-method-getStore'> /**
- </span> * Returns the store associated with this ComboBox.
- * @return {Ext.data.Store} The store
- */
- getStore : function(){
- return this.store;
- },
- beforeBlur: function() {
- this.doQueryTask.cancel();
- this.assertValue();
- },
- // private
- assertValue: function() {
- var me = this,
- value = me.getRawValue(),
- rec;
- if (me.forceSelection) {
- if (me.multiSelect) {
- // For multiselect, check that the current displayed value matches the current
- // selection, if it does not then revert to the most recent selection.
- if (value !== me.getDisplayValue()) {
- me.setValue(me.lastSelection);
- }
- } else {
- // For single-select, match the displayed value to a record and select it,
- // if it does not match a record then revert to the most recent selection.
- rec = me.findRecordByDisplay(value);
- if (rec) {
- me.select(rec);
- } else {
- me.setValue(me.lastSelection);
- }
- }
- }
- me.collapse();
- },
- onTypeAhead: function() {
- var me = this,
- displayField = me.displayField,
- record = me.store.findRecord(displayField, me.getRawValue()),
- boundList = me.getPicker(),
- newValue, len, selStart;
- if (record) {
- newValue = record.get(displayField);
- len = newValue.length;
- selStart = me.getRawValue().length;
- boundList.highlightItem(boundList.getNode(record));
- if (selStart !== 0 && selStart !== len) {
- me.setRawValue(newValue);
- me.selectText(selStart, newValue.length);
- }
- }
- },
- // invoked when a different store is bound to this combo
- // than the original
- resetToDefault: Ext.emptyFn,
-
- beforeReset: function() {
- this.callParent();
- this.clearFilter();
- },
-
- onUnbindStore: function(store) {
- var picker = this.picker;
- if (!store && picker) {
- picker.bindStore(null);
- }
- this.clearFilter();
- },
-
- onBindStore: function(store, initial) {
- var picker = this.picker;
- if (!initial) {
- this.resetToDefault();
- }
- if (picker) {
- picker.bindStore(store);
- }
- },
-
- getStoreListeners: function() {
- var me = this;
-
- return {
- beforeload: me.onBeforeLoad,
- clear: me.onClear,
- datachanged: me.onDataChanged,
- load: me.onLoad,
- exception: me.onException,
- remove: me.onRemove
- };
- },
-
- onBeforeLoad: function(){
- // If we're remote loading, the load mask will show which will trigger a deslectAll.
- // This selection change will trigger the collapse in onListSelectionChange. As such
- // we'll veto it for now and restore selection listeners when we've loaded.
- ++this.ignoreSelection;
- },
-
- onDataChanged: function() {
- var me = this;
- if (me.resizeComboToGrow()) {
- me.updateLayout();
- }
- },
- onClear: function() {
- var me = this;
- if (me.resizeComboToGrow()) {
- me.removingRecords = true;
- me.onDataChanged();
- }
- },
- onRemove: function() {
- var me = this;
- if (me.resizeComboToGrow()) {
- me.removingRecords = true;
- }
- },
- onException: function(){
- if (this.ignoreSelection > 0) {
- --this.ignoreSelection;
- }
- this.collapse();
- },
- onLoad: function() {
- var me = this,
- value = me.value;
- if (me.ignoreSelection > 0) {
- --me.ignoreSelection;
- }
- // If performing a remote query upon the raw value...
- if (me.rawQuery) {
- me.rawQuery = false;
- me.syncSelection();
- if (me.picker && !me.picker.getSelectionModel().hasSelection()) {
- me.doAutoSelect();
- }
- }
- // If store initial load or triggerAction: 'all' trigger click.
- else {
- // Set the value on load
- if (me.value || me.value === 0) {
- me.setValue(me.value);
- } else {
- // There's no value.
- // Highlight the first item in the list if autoSelect: true
- if (me.store.getCount()) {
- me.doAutoSelect();
- } else {
- // assign whatever empty value we have to prevent change from firing
- me.setValue(me.value);
- }
- }
- }
- },
- <span id='Ext-form-field-ComboBox-method-doRawQuery'> /**
- </span> * @private
- * Execute the query with the raw contents within the textfield.
- */
- doRawQuery: function() {
- this.doQuery(this.getRawValue(), false, true);
- },
- <span id='Ext-form-field-ComboBox-method-doQuery'> /**
- </span> * Executes a query to filter the dropdown list. Fires the {@link #beforequery} event prior to performing the query
- * allowing the query action to be canceled if needed.
- *
- * @param {String} queryString The SQL query to execute
- * @param {Boolean} [forceAll=false] `true` to force the query to execute even if there are currently fewer characters in
- * the field than the minimum specified by the `{@link #minChars}` config option. It also clears any filter
- * previously saved in the current store.
- * @param {Boolean} [rawQuery=false] Pass as true if the raw typed value is being used as the query string. This causes the
- * resulting store load to leave the raw value undisturbed.
- * @return {Boolean} true if the query was permitted to run, false if it was cancelled by a {@link #beforequery}
- * handler.
- */
- doQuery: function(queryString, forceAll, rawQuery) {
- queryString = queryString || '';
- // store in object and pass by reference in 'beforequery'
- // so that client code can modify values.
- var me = this,
- qe = {
- query: queryString,
- forceAll: forceAll,
- combo: me,
- cancel: false
- },
- store = me.store,
- isLocalMode = me.queryMode === 'local',
- needsRefresh;
- if (me.fireEvent('beforequery', qe) === false || qe.cancel) {
- return false;
- }
- // get back out possibly modified values
- queryString = qe.query;
- forceAll = qe.forceAll;
- // query permitted to run
- if (forceAll || (queryString.length >= me.minChars)) {
- // expand before starting query so LoadMask can position itself correctly
- me.expand();
- // make sure they aren't querying the same thing
- if (!me.queryCaching || me.lastQuery !== queryString) {
- me.lastQuery = queryString;
- if (isLocalMode) {
- // forceAll means no filtering - show whole dataset.
- store.suspendEvents();
- needsRefresh = me.clearFilter();
- if (queryString || !forceAll) {
- me.activeFilter = new Ext.util.Filter({
- root: 'data',
- property: me.displayField,
- value: queryString
- });
- store.filter(me.activeFilter);
- needsRefresh = true;
- } else {
- delete me.activeFilter;
- }
- store.resumeEvents();
- if (me.rendered && needsRefresh) {
- me.getPicker().refresh();
- }
- } else {
- // Set flag for onLoad handling to know how the Store was loaded
- me.rawQuery = rawQuery;
- // In queryMode: 'remote', we assume Store filters are added by the developer as remote filters,
- // and these are automatically passed as params with every load call, so we do *not* call clearFilter.
- if (me.pageSize) {
- // if we're paging, we've changed the query so start at page 1.
- me.loadPage(1);
- } else {
- store.load({
- params: me.getParams(queryString)
- });
- }
- }
- }
- // Clear current selection if it does not match the current value in the field
- if (me.getRawValue() !== me.getDisplayValue()) {
- me.ignoreSelection++;
- me.picker.getSelectionModel().deselectAll();
- me.ignoreSelection--;
- }
- if (isLocalMode) {
- me.doAutoSelect();
- }
- if (me.typeAhead) {
- me.doTypeAhead();
- }
- }
- return true;
- },
-
- <span id='Ext-form-field-ComboBox-method-clearFilter'> /**
- </span> * Clears any previous filters applied by the combo to the store
- * @private
- * @return {Boolean} True if a filter was removed
- */
- clearFilter: function() {
- var store = this.store,
- filter = this.activeFilter,
- filters = store.filters,
- remaining;
-
- if (filter) {
- if (filters.getCount() > 1) {
- // More than 1 existing filter
- filters.remove(filter);
- remaining = filters.getRange();
- }
- store.clearFilter(true);
- if (remaining) {
- store.filter(remaining);
- }
- }
- return !!filter;
- },
- loadPage: function(pageNum){
- this.store.loadPage(pageNum, {
- params: this.getParams(this.lastQuery)
- });
- },
- onPageChange: function(toolbar, newPage){
- /*
- * Return false here so we can call load ourselves and inject the query param.
- * We don't want to do this for every store load since the developer may load
- * the store through some other means so we won't add the query param.
- */
- this.loadPage(newPage);
- return false;
- },
- // private
- getParams: function(queryString) {
- var params = {},
- param = this.queryParam;
- if (param) {
- params[param] = queryString;
- }
- return params;
- },
- <span id='Ext-form-field-ComboBox-method-doAutoSelect'> /**
- </span> * @private
- * If the autoSelect config is true, and the picker is open, highlights the first item.
- */
- doAutoSelect: function() {
- var me = this,
- picker = me.picker,
- lastSelected, itemNode;
- if (picker && me.autoSelect && me.store.getCount() > 0) {
- // Highlight the last selected item and scroll it into view
- lastSelected = picker.getSelectionModel().lastSelected;
- itemNode = picker.getNode(lastSelected || 0);
- if (itemNode) {
- picker.highlightItem(itemNode);
- picker.listEl.scrollChildIntoView(itemNode, false);
- }
- }
- },
- doTypeAhead: function() {
- if (!this.typeAheadTask) {
- this.typeAheadTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
- }
- if (this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE) {
- this.typeAheadTask.delay(this.typeAheadDelay);
- }
- },
- onTriggerClick: function() {
- var me = this;
- if (!me.readOnly && !me.disabled) {
- if (me.isExpanded) {
- me.collapse();
- } else {
- me.onFocus({});
- if (me.triggerAction === 'all') {
- me.doQuery(me.allQuery, true);
- } else {
- me.doQuery(me.getRawValue(), false, true);
- }
- }
- me.inputEl.focus();
- }
- },
- // store the last key and doQuery if relevant
- onKeyUp: function(e, t) {
- var me = this,
- key = e.getKey();
- if (!me.readOnly && !me.disabled && me.editable) {
- me.lastKey = key;
- // we put this in a task so that we can cancel it if a user is
- // in and out before the queryDelay elapses
- // perform query w/ any normal key or backspace or delete
- if (!e.isSpecialKey() || key == e.BACKSPACE || key == e.DELETE) {
- me.doQueryTask.delay(me.queryDelay);
- }
- }
- if (me.enableKeyEvents) {
- me.callParent(arguments);
- }
- },
- initEvents: function() {
- var me = this;
- me.callParent();
- /*
- * Setup keyboard handling. If enableKeyEvents is true, we already have
- * a listener on the inputEl for keyup, so don't create a second.
- */
- if (!me.enableKeyEvents) {
- me.mon(me.inputEl, 'keyup', me.onKeyUp, me);
- }
- },
- onDestroy: function() {
- this.bindStore(null);
- this.callParent();
- },
- // The picker (the dropdown) must have its zIndex managed by the same ZIndexManager which is
- // providing the zIndex of our Container.
- onAdded: function() {
- var me = this;
- me.callParent(arguments);
- if (me.picker) {
- me.picker.ownerCt = me.up('[floating]');
- me.picker.registerWithOwnerCt();
- }
- },
- createPicker: function() {
- var me = this,
- picker,
- pickerCfg = Ext.apply({
- xtype: 'boundlist',
- pickerField: me,
- selModel: {
- mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
- },
- floating: true,
- hidden: true,
- store: me.store,
- displayField: me.displayField,
- focusOnToFront: false,
- pageSize: me.pageSize,
- tpl: me.tpl
- }, me.listConfig, me.defaultListConfig);
- picker = me.picker = Ext.widget(pickerCfg);
- if (me.pageSize) {
- picker.pagingToolbar.on('beforechange', me.onPageChange, me);
- }
- me.mon(picker, {
- itemclick: me.onItemClick,
- refresh: me.onListRefresh,
- scope: me
- });
- me.mon(picker.getSelectionModel(), {
- beforeselect: me.onBeforeSelect,
- beforedeselect: me.onBeforeDeselect,
- selectionchange: me.onListSelectionChange,
- scope: me
- });
- return picker;
- },
- alignPicker: function(){
- var me = this,
- picker = me.getPicker(),
- heightAbove = me.getPosition()[1] - Ext.getBody().getScroll().top,
- heightBelow = Ext.Element.getViewHeight() - heightAbove - me.getHeight(),
- space = Math.max(heightAbove, heightBelow);
- // Allow the picker to height itself naturally.
- if (picker.height) {
- delete picker.height;
- picker.updateLayout();
- }
- // Then ensure that vertically, the dropdown will fit into the space either above or below the inputEl.
- if (picker.getHeight() > space - 5) {
- picker.setHeight(space - 5); // have some leeway so we aren't flush against
- }
- me.callParent();
- },
- onListRefresh: function() {
- this.alignPicker();
- this.syncSelection();
- },
- onItemClick: function(picker, record){
- /*
- * If we're doing single selection, the selection change events won't fire when
- * clicking on the selected element. Detect it here.
- */
- var me = this,
- selection = me.picker.getSelectionModel().getSelection(),
- valueField = me.valueField;
- if (!me.multiSelect && selection.length) {
- if (record.get(valueField) === selection[0].get(valueField)) {
- // Make sure we also update the display value if it's only partial
- me.displayTplData = [record.data];
- me.setRawValue(me.getDisplayValue());
- me.collapse();
- }
- }
- },
- onBeforeSelect: function(list, record) {
- return this.fireEvent('beforeselect', this, record, record.index);
- },
- onBeforeDeselect: function(list, record) {
- return this.fireEvent('beforedeselect', this, record, record.index);
- },
- onListSelectionChange: function(list, selectedRecords) {
- var me = this,
- isMulti = me.multiSelect,
- hasRecords = selectedRecords.length > 0;
- // Only react to selection if it is not called from setValue, and if our list is
- // expanded (ignores changes to the selection model triggered elsewhere)
- if (!me.ignoreSelection && me.isExpanded) {
- if (!isMulti) {
- Ext.defer(me.collapse, 1, me);
- }
- /*
- * Only set the value here if we're in multi selection mode or we have
- * a selection. Otherwise setValue will be called with an empty value
- * which will cause the change event to fire twice.
- */
- if (isMulti || hasRecords) {
- me.setValue(selectedRecords, false);
- }
- if (hasRecords) {
- me.fireEvent('select', me, selectedRecords);
- }
- me.inputEl.focus();
- }
- },
- <span id='Ext-form-field-ComboBox-method-onExpand'> /**
- </span> * @private
- * Enables the key nav for the BoundList when it is expanded.
- */
- onExpand: function() {
- var me = this,
- keyNav = me.listKeyNav,
- selectOnTab = me.selectOnTab,
- picker = me.getPicker();
- // Handle BoundList navigation from the input field. Insert a tab listener specially to enable selectOnTab.
- if (keyNav) {
- keyNav.enable();
- } else {
- keyNav = me.listKeyNav = new Ext.view.BoundListKeyNav(this.inputEl, {
- boundList: picker,
- forceKeyDown: true,
- tab: function(e) {
- if (selectOnTab) {
- this.selectHighlighted(e);
- me.triggerBlur();
- }
- // Tab key event is allowed to propagate to field
- return true;
- }
- });
- }
- // While list is expanded, stop tab monitoring from Ext.form.field.Trigger so it doesn't short-circuit selectOnTab
- if (selectOnTab) {
- me.ignoreMonitorTab = true;
- }
- Ext.defer(keyNav.enable, 1, keyNav); //wait a bit so it doesn't react to the down arrow opening the picker
- me.inputEl.focus();
- },
- <span id='Ext-form-field-ComboBox-method-onCollapse'> /**
- </span> * @private
- * Disables the key nav for the BoundList when it is collapsed.
- */
- onCollapse: function() {
- var me = this,
- keyNav = me.listKeyNav;
- if (keyNav) {
- keyNav.disable();
- me.ignoreMonitorTab = false;
- }
- },
- <span id='Ext-form-field-ComboBox-method-select'> /**
- </span> * Selects an item by a {@link Ext.data.Model Model}, or by a key value.
- * @param {Object} r
- */
- select: function(r) {
- this.setValue(r, true);
- },
- <span id='Ext-form-field-ComboBox-method-findRecord'> /**
- </span> * Finds the record by searching for a specific field/value combination.
- * @param {String} field The name of the field to test.
- * @param {Object} value The value to match the field against.
- * @return {Ext.data.Model} The matched record or false.
- */
- findRecord: function(field, value) {
- var ds = this.store,
- idx = ds.findExact(field, value);
- return idx !== -1 ? ds.getAt(idx) : false;
- },
- <span id='Ext-form-field-ComboBox-method-findRecordByValue'> /**
- </span> * Finds the record by searching values in the {@link #valueField}.
- * @param {Object} value The value to match the field against.
- * @return {Ext.data.Model} The matched record or false.
- */
- findRecordByValue: function(value) {
- return this.findRecord(this.valueField, value);
- },
- <span id='Ext-form-field-ComboBox-method-findRecordByDisplay'> /**
- </span> * Finds the record by searching values in the {@link #displayField}.
- * @param {Object} value The value to match the field against.
- * @return {Ext.data.Model} The matched record or false.
- */
- findRecordByDisplay: function(value) {
- return this.findRecord(this.displayField, value);
- },
- <span id='Ext-form-field-ComboBox-method-setValue'> /**
- </span> * Sets the specified value(s) into the field. For each value, if a record is found in the {@link #store} that
- * matches based on the {@link #valueField}, then that record's {@link #displayField} will be displayed in the
- * field. If no match is found, and the {@link #valueNotFoundText} config option is defined, then that will be
- * displayed as the default field text. Otherwise a blank value will be shown, although the value will still be set.
- * @param {String/String[]} value The value(s) to be set. Can be either a single String or {@link Ext.data.Model},
- * or an Array of Strings or Models.
- * @return {Ext.form.field.Field} this
- */
- setValue: function(value, doSelect) {
- var me = this,
- valueNotFoundText = me.valueNotFoundText,
- inputEl = me.inputEl,
- i, len, record,
- dataObj,
- matchedRecords = [],
- displayTplData = [],
- processedValue = [];
- if (me.store.loading) {
- // Called while the Store is loading. Ensure it is processed by the onLoad method.
- me.value = value;
- me.setHiddenValue(me.value);
- return me;
- }
- // This method processes multi-values, so ensure value is an array.
- value = Ext.Array.from(value);
- // Loop through values, matching each from the Store, and collecting matched records
- for (i = 0, len = value.length; i < len; i++) {
- record = value[i];
- if (!record || !record.isModel) {
- record = me.findRecordByValue(record);
- }
- // record found, select it.
- if (record) {
- matchedRecords.push(record);
- displayTplData.push(record.data);
- processedValue.push(record.get(me.valueField));
- }
- // record was not found, this could happen because
- // store is not loaded or they set a value not in the store
- else {
- // If we are allowing insertion of values not represented in the Store, then push the value and
- // create a fake record data object to push as a display value for use by the displayTpl
- if (!me.forceSelection) {
- processedValue.push(value[i]);
- dataObj = {};
- dataObj[me.displayField] = value[i];
- displayTplData.push(dataObj);
- // TODO: Add config to create new records on selection of a value that has no match in the Store
- }
- // Else, if valueNotFoundText is defined, display it, otherwise display nothing for this value
- else if (Ext.isDefined(valueNotFoundText)) {
- displayTplData.push(valueNotFoundText);
- }
- }
- }
- // Set the value of this field. If we are multiselecting, then that is an array.
- me.setHiddenValue(processedValue);
- me.value = me.multiSelect ? processedValue : processedValue[0];
- if (!Ext.isDefined(me.value)) {
- me.value = null;
- }
- me.displayTplData = displayTplData; //store for getDisplayValue method
- me.lastSelection = me.valueModels = matchedRecords;
- if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
- inputEl.removeCls(me.emptyCls);
- }
- // Calculate raw value from the collection of Model data
- me.setRawValue(me.getDisplayValue());
- me.checkChange();
- if (doSelect !== false) {
- me.syncSelection();
- }
- me.applyEmptyText();
- return me;
- },
- <span id='Ext-form-field-ComboBox-method-setHiddenValue'> /**
- </span> * @private
- * Set the value of {@link #hiddenDataEl}
- * Dynamically adds and removes input[type=hidden] elements
- */
- setHiddenValue: function(values){
- var me = this,
- name = me.hiddenName,
- i,
- dom, childNodes, input, valueCount, childrenCount;
-
- if (!me.hiddenDataEl || !name) {
- return;
- }
- values = Ext.Array.from(values);
- dom = me.hiddenDataEl.dom;
- childNodes = dom.childNodes;
- input = childNodes[0];
- valueCount = values.length;
- childrenCount = childNodes.length;
-
- if (!input && valueCount > 0) {
- me.hiddenDataEl.update(Ext.DomHelper.markup({
- tag: 'input',
- type: 'hidden',
- name: name
- }));
- childrenCount = 1;
- input = dom.firstChild;
- }
- while (childrenCount > valueCount) {
- dom.removeChild(childNodes[0]);
- -- childrenCount;
- }
- while (childrenCount < valueCount) {
- dom.appendChild(input.cloneNode(true));
- ++ childrenCount;
- }
- for (i = 0; i < valueCount; i++) {
- childNodes[i].value = values[i];
- }
- },
- <span id='Ext-form-field-ComboBox-method-getDisplayValue'> /**
- </span> * @private Generates the string value to be displayed in the text field for the currently stored value
- */
- getDisplayValue: function() {
- return this.displayTpl.apply(this.displayTplData);
- },
- getValue: function() {
- // If the user has not changed the raw field value since a value was selected from the list,
- // then return the structured value from the selection. If the raw field value is different
- // than what would be displayed due to selection, return that raw value.
- var me = this,
- picker = me.picker,
- rawValue = me.getRawValue(), //current value of text field
- value = me.value; //stored value from last selection or setValue() call
- if (me.getDisplayValue() !== rawValue) {
- value = rawValue;
- me.value = me.displayTplData = me.valueModels = null;
- if (picker) {
- me.ignoreSelection++;
- picker.getSelectionModel().deselectAll();
- me.ignoreSelection--;
- }
- }
- return value;
- },
- getSubmitValue: function() {
- return this.getValue();
- },
- isEqual: function(v1, v2) {
- var fromArray = Ext.Array.from,
- i, len;
- v1 = fromArray(v1);
- v2 = fromArray(v2);
- len = v1.length;
- if (len !== v2.length) {
- return false;
- }
- for(i = 0; i < len; i++) {
- if (v2[i] !== v1[i]) {
- return false;
- }
- }
- return true;
- },
- <span id='Ext-form-field-ComboBox-method-clearValue'> /**
- </span> * Clears any value currently set in the ComboBox.
- */
- clearValue: function() {
- this.setValue([]);
- },
- <span id='Ext-form-field-ComboBox-method-syncSelection'> /**
- </span> * @private Synchronizes the selection in the picker to match the current value of the combobox.
- */
- syncSelection: function() {
- var me = this,
- picker = me.picker,
- selection, selModel,
- values = me.valueModels || [],
- vLen = values.length, v, value;
- if (picker) {
- // From the value, find the Models that are in the store's current data
- selection = [];
- for (v = 0; v < vLen; v++) {
- value = values[v];
- if (value && value.isModel && me.store.indexOf(value) >= 0) {
- selection.push(value);
- }
- }
- // Update the selection to match
- me.ignoreSelection++;
- selModel = picker.getSelectionModel();
- selModel.deselectAll();
- if (selection.length) {
- selModel.select(selection);
- }
- me.ignoreSelection--;
- }
- },
-
- onEditorTab: function(e){
- var keyNav = this.listKeyNav;
-
- if (this.selectOnTab && keyNav) {
- keyNav.selectHighlighted(e);
- }
- }
- });
- </pre>
- </body>
- </html>
|