Ext.define('Ext.form.ComboBox', {
extend:'Ext.form.Picker',
requires: ['Ext.util.DelayedTask', 'Ext.EventObject', 'Ext.view.BoundList', 'Ext.view.BoundListKeyNav', 'Ext.data.StoreMgr'],
alias: ['widget.combobox', 'widget.combo'],
/**
* @cfg {String} triggerCls
* 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.
* Defaults to 'x-form-arrow-trigger' for ComboBox.
*/
triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
/**
* @cfg {Ext.data.Store/Array} store The data source to which this combo is bound (defaults to undefined).
* Acceptable values for this property are:
*
* - any {@link Ext.data.Store Store} subclass
* - an Array : Arrays will be converted to a {@link Ext.data.ArrayStore} 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}.
*/
/**
* @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}. (Defaults to false.)
*/
multiSelect: false,
/**
* @cfg {String} delimiter
* The character(s) used to separate the {@link #displayField display values} of multiple selected items
* when {@link #multiSelect} = true. Defaults to ', '.
*/
delimiter: ', ',
/**
* @cfg {String} displayField The underlying {@link Ext.data.Field#name data field name} to bind to this
* ComboBox (defaults to 'text').
* See also {@link #valueField}.
* TODO still valid? Note: if using a ComboBox in an {@link Ext.grid.EditorGridPanel Editor Grid} a
* {@link Ext.grid.Column#renderer renderer} will be needed to show the displayField when the editor is not
* active.
*/
displayField: 'text',
/**
* @cfg {String} valueField
* @required
* The underlying {@link Ext.data.Field#name data value name} to bind to this ComboBox (defaults to match
* the value of the {@link #displayField} config).
* TODO still valid? Note: use of a valueField requires the user to make a selection in order for a value to be
* mapped. See also {@link #hiddenName}, {@link #hiddenValue}, and {@link #displayField}.
*/
/**
* @cfg {String} triggerAction The action to execute when the trigger is clicked.
*
* - 'all' : Default
*
{@link #doQuery run the query} specified by the {@link #allQuery} config option
* - 'query' :
*
{@link #doQuery run the query} using the {@link Ext.form.BaseField#getRawValue raw value}.
*
* See also {@link #queryParam}.
*/
triggerAction: 'all',
/**
* @cfg {String} allQuery The text query to send to the server to return all records for the list
* with no filtering (defaults to '')
*/
allQuery: '',
/**
* @cfg {String} queryParam Name of the query ({@link Ext.data.Store#baseParam baseParam} name for the store)
* as it will be passed on the querystring (defaults to 'query')
*/
queryParam: 'query',
/**
* @cfg {String} queryMode
* The mode for queries. Acceptable values are:
*
* - 'remote' : Default
*
Automatically loads the {@link #store} the first time the trigger
* is clicked. If you do not want the store to be automatically loaded the first time the trigger is
* clicked, set to 'local' and manually load the store. To force a requery of the store
* every time the trigger is clicked see {@link #lastQuery}.
* - 'local' :
*
ComboBox loads local data
*
var combo = new Ext.form.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',
queryCaching: true,
/**
* @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')
*/
/**
* @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.Trigger#editable editable} = false).
*/
/**
* @cfg {Boolean} autoSelect true to select the first result gathered by the data store (defaults
* to true). A false value would require a manual selection from the dropdown list to set the components value
* unless the value of ({@link #typeAhead}) were true.
*/
autoSelect: true,
/**
* @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 (defaults
* to false)
*/
typeAhead: false,
/**
* @cfg {Number} typeAheadDelay The length of time in milliseconds to wait until the typeahead text is displayed
* if {@link #typeAhead} = true (defaults to 250)
*/
typeAheadDelay: 250,
/**
* @cfg {Boolean} selectOnTab
* Whether the Tab key should select the currently highlighted item. Defaults to true.
*/
selectOnTab: true,
/**
* @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 (defaults to false)
*/
forceSelection: false,
/**
* 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.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.ComboBox({
...
queryMode: 'local',
triggerAction: 'all',
lastQuery: ''
});
*
* @property lastQuery
* @type String
*/
///// Config properties for the BoundList:
// TODO consider removing all of these in favor of a single listConfig object which would be passed
// directly to the BoundList constructor after combination with default configs. That would be
// simpler and more flexible as any aspect of the BoundList could be customized.
/**
* @cfg {String} listEmptyText The empty text to display in the data view if no items are found.
* (defaults to '')
*/
listEmptyText: '',
/**
* @cfg {String} listLoadingText The text to display in the dropdown list while data is loading. Only applies
* when {@link #mode} = 'remote' (defaults to 'Loading...')
*/
listLoadingText: 'Loading...',
/**
* @cfg {Number} listMaxHeight The maximum height in pixels of the dropdown list before scrollbars are shown
* (defaults to 300)
*/
listMaxHeight: 300,
/**
* @cfg {Number} listWidth The width in pixels of the dropdown list (defaults to the width of the ComboBox
* field).
*/
/**
* @cfg {Function} getInnerTpl If specified, will be used to generate the template for the markup inside
* each item in the dropdown list. Defaults to the {@link Ext.view.BoundList}'s default behavior, which
* is to display the value of each item's {@link #displayField}.
* @return {String} The template string
*/
//
deprecatedProperties: [
// slated to be removed/yet to be implemented
'autoCreate',
'clearFilterOnReset',
'handleHeight',
'hiddenId',
'hiddenName',
'itemSelector', // could be passed to BoundList config
'lazyInit',
'lazyRender',
'listAlign', // -> pickerAlign
'listClass', // could be passed to BoundList config's cls
'loadingText', // -> listLoadingText
'maxHeight', // -> listMaxHeight
'minHeight', // -> ???
'minListWidth', // -> ???
'mode', // -> queryMode
'pageSize',
'resizable', // could be passed to BoundList config
'selectedClass', // could be passed to BoundList config's selectedItemCls
'shadow', // could be passed to BoundList config's floating.shadow
'title',
'tpl', // -> getInnerTpl
'transform',
'triggerClass', // -> triggerCls,
'valueNotFoundText' // -> ???
],
//
/**
* @type Boolean
* @property isExpanded
*/
initComponent: function() {
var me = this,
isLocalMode = me.queryMode === 'local',
isDefined = Ext.isDefined;
//
if (!me.store) {
throw "Ext.form.ComboBox: No store defined on ComboBox.";
}
if (me.typeAhead && me.multiSelect) {
throw "Ext.form.ComboBox: typeAhead and multiSelect are mutually exclusive options.";
}
if (me.typeAhead && !me.editable) {
throw "Ext.form.ComboBox: typeAhead must be used in conjunction with editable.";
}
if (me.selectOnFocus && !me.editable) {
throw "Ext.form.ComboBox: selectOnFocus must be used in conjunction with editable.";
}
var dp = me.deprecatedProperties,
ln = dp.length,
i = 0;
for (; i < ln; i++) {
if (isDefined(me[dp[i]])) {
throw dp[i] + " is no longer supported.";
}
}
//
this.addEvents(
// TODO need beforeselect?
/**
* @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.ComboBox query : String forceAll : Boolean cancel : Boolean