PDA

View Full Version : A little help and advice new Component Lookup Multiple



dewie
6 Mar 2008, 11:56 AM
For my first testproject in Ext i'm currently developing in extjs with adobe air.
I needed a couple of special fields :

- edit lookup combo (user can lookup item, or type another new item)
(realized with a standard ComboBox

- edit lookup combo than can hold and lookup multiple items

This one was al little bit trickier, i works but i still have some problems :

The js code for the component :

Ext.form.ComboBoxMulti = function(config) {
this.hideTrigger= true,
this.itemSeperator = "\n",
Ext.form.ComboBoxMulti.superclass.constructor.call (this, config);
};

Ext.extend(Ext.form.ComboBoxMulti, Ext.form.ComboBox, {

onRender : function(ct, position){
Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
if(this.hiddenName){
this.hiddenField = this.el.insertSibling({tag:'textarea',name: this.hiddenName, id: (this.hiddenId||this.hiddenName)},
'before', true);
this.hiddenField.value =
this.hiddenValue !== undefined ? this.hiddenValue :
this.value !== undefined ? this.value : '';

// prevent input submission
this.el.dom.removeAttribute('name');
}
if(Ext.isGecko){
this.el.dom.setAttribute('autocomplete', 'off');
}

if(!this.lazyInit){
this.initList();
}else{
this.on('focus', this.initList, this, {single: true});
}

if(!this.editable){
this.editable = true;
this.setEditable(false);
}
},

onSelect : function(record, index){
if(this.fireEvent('beforeselect', this, record, index) !== false){
this.setMultiValue(record.data[this.valueField || this.displayField]);
this.collapse();
this.setRawValue('');
this.fireEvent('select', this, record, index);
}
},

setValue: function(v){
Ext.form.ComboBoxMulti.superclass.setValue.call(this,v);
this.setRawValue('');
},

setMultiValue: function(v){
if (this.hiddenField.value != '') {
this.hiddenField.value += this.itemSeperator
}
this.hiddenField.value += v
},

fireKey : function(e){
if (e.getKey() == '13' && this.getRawValue() != '') {
this.setMultiValue(this.getRawValue());
this.setRawValue('');


}
else {

if (e.isNavKeyPress() && !this.isExpanded() && !this.delayedCheck) {
this.fireEvent("specialkey", this, e);
}
}
},




});


I create the component with :


new Ext.form.ComboBoxMulti(
{
xtype: 'combo',
fieldLabel: 'Afmetingen',

//if we enable typeAhead it will be querying database
//so we may not want typeahead consuming resources
typeAhead: false,
triggerAction: 'all',
allowBlank: true,
editable: true,
hiddenName: 'certificate[measurements]',
//By enabling lazyRender this prevents the combo box
//from rendering until requested
lazyRender: true,//should always be true for editor



//where to get the data for our combobox
store: store_measurements = new Ext.data.Store({
remoteSort : true,
autoLoad: true,
proxy: new Ext.data.HttpProxy({
url: '/customers/4/clients/lookup.json',
method: 'GET',
}),
reader: new Ext.data.JsonReader(
{
root: 'records',//name of the property that is container for an Array of row objects
id: 'id'//the property within each row object that provides an ID for the record (optional)
},
[
{name: 'id'},{name: 'name'},//name of the field in the stock table (not the industry table)
]
),
}),
mode: 'remote',


//the underlying data field name to bind to this
//ComboBox (defaults to undefined if mode = 'remote'
//or 'text' if transforming a select)
displayField: 'name',
//the underlying value field name to bind to this
//ComboBox
valueField: 'name',



typeAhead: true,



anchor: '95%',



label: 'Afmetingen',



})

The only thing i have changed is onrender so that not a hidden input is created but a textarea. Also i have overridden some options to handle the events on list select ed (so that mulitple items can be selected)

This all works, but it is ugly as hell :)

What i would like to do is :

- Style the textarea according to the styling of the combobox (sameWidth make height optional with config)
put the combobox on a new line

- Clean this code up, this works but i don't think this is the nicest way to handlse something like this. Is it better to make a plugin of it or a default xtype , and if yes can anyone give me some pointers how to do this ?

Kind regards daniel