/**
* @class Ext.form.Select
* @extends Ext.form.Text
* Simple Select field wrapper. Example usage:
new Ext.form.Select({
options: [
{text: 'First Option', value: 'first'},
{text: 'Second Option', value: 'second'},
{text: 'Third Option', value: 'third'}
]
});
* @xtype selectfield
*/
Ext.form.Select = Ext.extend(Ext.form.Text, {
ui: 'select',
/**
* @cfg {Boolean} useClearIcon @hide
*/
/**
* @cfg {String/Integer} valueField The underlying {@link Ext.data.Field#name data value name} (or numeric Array index) to bind to this
* Select control. (defaults to 'value')
*/
valueField: 'value',
/**
* @cfg {String/Integer} displayField The underlying {@link Ext.data.Field#name data value name} (or numeric Array index) to bind to this
* Select control. This resolved value is the visibly rendered value of the available selection options.
* (defaults to 'text')
*/
displayField: 'text',
/**
* @cfg {Ext.data.Store} store (Optional) store instance used to provide selection options data.
*/
/**
* @cfg {Array} options (Optional) An array of select options.
[
{text: 'First Option', value: 'first'},
{text: 'Second Option', value: 'second'},
{text: 'Third Option', value: 'third'}
]
* Note: option object member names should correspond with defined {@link #valueField valueField} and {@link #displayField displayField} values.
* This config will be ignore if a {@link #store store} instance is provided
*/
/**
* @cfg {String} hiddenName Specify a hiddenName if you're using the {@link Ext.form.FormPanel#standardSubmit standardSubmit} option.
* This name will be used to post the underlying value of the select to the server.
*/
// @cfg {Number} tabIndex @hide
tabIndex: -1,
// @cfg {Boolean} useMask @hide
useMask: true,
// @private
initComponent: function() {
var options = this.options;
if (this.store) {
this.store = Ext.StoreMgr.lookup(this.store);
}
else {
this.store = new Ext.data.Store({
fields: [this.valueField, this.displayField]
});
if (options && Ext.isArray(options) && options.length > 0) {
this.setOptions(this.options);
}
}
Ext.form.Select.superclass.initComponent.call(this);
this.addEvents(
/**
* @event change
* Fires when an option selection has changed
* @param {Ext.form.Select} this
* @param {Mixed} value
*/
'change'
);
},
onRender: function(){
Ext.form.Select.superclass.onRender.apply(this, arguments);
var name = this.hiddenName;
if (name) {
this.hiddenField = this.el.insertSibling({
name: name,
tag: 'input',
type: 'hidden'
}, 'after');
}
},
getPicker: function() {
if (!this.picker) {
this.picker = new Ext.Picker({
slots: [{
align : 'center',
name : this.name,
valueField : this.valueField,
displayField: this.displayField,
value : this.getValue(),
store : this.store
}],
listeners: {
change: this.onPickerChange,
scope: this
}
});
}
return this.picker;
},
getListPanel: function() {
if (!this.listPanel) {
this.listPanel = new Ext.Panel({
floating : true,
stopMaskTapEvent : true,
hideOnMaskTap : true,
cls : 'x-select-overlay',
scroll : 'vertical',
items: {
xtype: 'list',
store: this.store,
itemId: 'list',
scroll: false,
itemTpl : [
'{' + this.displayField + '}',
''
],
listeners: {
select : this.onListSelect,
scope : this
}
}
});
}
return this.listPanel;
},
onMaskTap: function() {
if (this.disabled) {
return;
}
this.showComponent();
},
showComponent: function() {
if (Ext.is.Phone) {
this.getPicker().show();
}
else {
var listPanel = this.getListPanel(),
index = this.store.findExact(this.valueField, this.value);
listPanel.showBy(this.el, 'fade', false);
listPanel.down('#list').getSelectionModel().select(index != -1 ? index: 0, false, true);
}
},
onListSelect: function(selModel, selected) {
if (selected) {
this.setValue(selected.get(this.valueField));
this.fireEvent('change', this, this.getValue());
}
this.listPanel.hide({
type: 'fade',
out: true,
scope: this
});
},
onPickerChange: function(picker, value) {
var currentValue = this.getValue(),
newValue = value[this.name];
if (newValue != currentValue) {
this.setValue(newValue);
this.fireEvent('change', this, newValue);
}
},
// Inherited docs
setValue: function(value) {
var idx = 0,
hiddenField = this.hiddenField,
record;
if (value) {
idx = this.store.findExact(this.valueField, value)
}
record = this.store.getAt(idx);
if (record && this.rendered) {
this.fieldEl.dom.value = record.get(this.displayField);
this.value = record.get(this.valueField);
if (hiddenField) {
hiddenField.dom.value = this.value;
}
} else {
this.value = value;
}
// Temporary fix, the picker should sync with the store automatically by itself
if (this.picker) {
var pickerValue = {};
pickerValue[this.name] = this.value;
this.picker.setValue(pickerValue);
}
return this;
},
// Inherited docs
getValue: function(){
return this.value;
},
/**
* Updates the underlying <options> list with new values.
* @param {Array} options An array of options configurations to insert or append.
* @param {Boolean} append true to append the new options existing values.
selectBox.setOptions(
[ {text: 'First Option', value: 'first'},
{text: 'Second Option', value: 'second'},
{text: 'Third Option', value: 'third'}
]).setValue('third');
* Note: option object member names should correspond with defined {@link #valueField valueField} and
* {@link #displayField displayField} values.
* @return {Ext.form.Select} this
*/
setOptions: function(options, append) {
if (!options) {
this.store.clearData();
this.setValue(null);
}
else {
this.store.loadData(options, append);
}
},
destroy: function() {
Ext.form.Select.superclass.destroy.apply(this, arguments);
Ext.destroy(this.listPanel, this.picker, this.hiddenField);
}
});
Ext.reg('selectfield', Ext.form.Select);
//
//DEPRECATED - remove this in 1.0. See RC1 Release Notes for details
Ext.reg('select', Ext.form.Select);
//