PDA

View Full Version : Ext.ux.form.Pop(ulating)Combo



jsakalos
8 Feb 2009, 10:38 PM
Hi all,

sometimes we want to populate combo's store with some records before we actually call setValue. I've created a very simple extension for that.

How it works?
PopCombo's setValue method accept also object as argument, for example


var o = {value:1,records:[[0,'Item 1'],[1,'Item 2']]};
If such object is passed to setValue method, combo's store is first loaded with "records" member of passed object and then value is set to "value" member.

Demo: http://examples.extjs.eu/?ex=popcombo

Ext.ux.form.PopCombo source:


// vim: ts=4:sw=4:nu:fdc=4:nospell
/*global Ext */
/**
* @class Ext.ux.form.PopCombo
* @extends Ext.form.ComboBox
*
* Pop(ulating)Combo's setValue method accepts object as argument and implements
* special processing of the object. For example:
* <pre>
* var combo = new Ext.ux.form.PopCombo();
* var o = {value:1,records:[[0,'Item 1'],[1,'Item 2']]};
* combo.setValue(o);
* </pre>
* If records are found in the passed object the combo store is popupated with
* these records before the value is actually set.
*
* @author Ing. Jozef Sakáloš
* @copyright (c) 2009, by Ing. Jozef Sakáloš
* @date 9. February 2009
* @version 0.1
* @revision $Id: Ext.ux.form.PopCombo.js 553 2009-02-09 08:49:22Z jozo $
*
* @license Ext.ux.form.PopCombo.js is licensed under the terms of the Open Source
* LGPL 3.0 license. Commercial use is permitted to the extent that the
* code/component(s) do NOT become part of another Open Source or Commercially
* licensed development library or toolkit without explicit permission.
*
* <p>License details: <a href="http://www.gnu.org/licenses/lgpl.html"
* target="_blank">http://www.gnu.org/licenses/lgpl.html</a></p>
*
* @forum 59406
*/

// create namespace
Ext.ns('Ext.ux.form');

/**
* Creates new Ext.ux.form.PopCombo
* @constructor
* @param {Object} config A config object
*/
Ext.ux.form.PopCombo = Ext.extend(Ext.form.ComboBox, {

// defaults
/**
* @cfg {Object} paramNames
* Defines names that are used for "value" and "records" members
* (defaults to {value:"value", records:"records"})
*/
paramNames:{value:'value', records:'records'}

,setValue:function(value) {
var val = value;
if('object' === typeof value && '[object Object]' === Object.prototype.toString.call(value)) {
if(undefined !== value[this.paramNames['records']]) {
this.store.loadData(value[this.paramNames['records']]);
}
val = value[this.paramNames['value']];
}
Ext.ux.form.PopCombo.superclass.setValue.call(this, val);
} // eo function setValue

}); // eo extend

// register xtype
Ext.reg('popcombo', Ext.ux.form.PopCombo);

// eof

Condor
9 Feb 2009, 12:19 AM
Could you explain why you used:

if('object' === typeof value
&& '[object Object]' === Object.prototype.toString.call(value)){
and not something like:

if(typeof value == 'object'
&& value[this.paramNames.value] !== undefined
&& value[this.paramNames.records] !== undefined){

jsakalos
9 Feb 2009, 12:26 AM
No specific reason. I just do not want that branch of code to be executed for non-objects.

If had the test you propose, I'd call standard setValue with and "incomplete" object, which would most likely fail.

In any case, I have no long-run experiences with all varieties of what users can pass to it. I'll wait for their responses and may change the test if it would be useful.

jsakalos
9 Feb 2009, 12:49 AM
I tested it a bit focusing on the "object test". If you pass undefined to standard setValue the combo is cleared. So if you pass:


popcombo.setValue({records:[[0,'item 0],[1,'item 1]]});

the store is populated and combo is cleared.

If you pass an object with empty records, setValue fails. So I've change the test that it now also accepts {value:3} w/o records member.

JBarton
5 May 2010, 2:19 PM
(I believe) this causes client validation to fire. Is there a way to prevent validation firing for those fields until after they are populated?

jsakalos
5 May 2010, 2:26 PM
Do you have a showcase?

JBarton
5 May 2010, 2:36 PM
Do you have a showcase?

i will try to set something up (i am working on a corp internal app). I had to add a null check to your PopCombo, because if there is a null keyword in a JSON string, errors get thrown in IE.



Settings.PopCombo = Ext.extend(Ext.form.ComboBox, {

paramNames:{value:'value', records:'records'},
setValue:function(value) {
var val = value;
if (value !== null){ //added null check to fix IE bug
if('object' === typeof value && '[object Object]' === Object.prototype.toString.call(value)) {
if(undefined !== value[this.paramNames['records']]) {
this.store.loadData(value[this.paramNames['records']]);
}
val = value[this.paramNames['value']];
}
Settings.PopCombo.superclass.setValue.call(this, val);
}
} // eo function setValue

}); // eo extend


and this is an example of my popcombo. I've just started using this framework a few days ago, so forgive me if I've missed something obvious.



{
name:'reqgroup',
fieldLabel:'<font color="red">*</font> Requestor Group',
allowBlank: false,
width:190,
editable: false,
xtype:'popcombo',
triggerAction:'all',
mode:'local',
store:new Ext.data.SimpleStore({
fields:['value', 'text']
}),
displayField:'text',
valueField:'value',
hiddenName:'hidden_reqgroup'
}


and the surrounding formpanel has monitorValid set to true. normal form fields don't fire validation until a blur event fires on them, but Im guessing the overidden setValue function is activating the validation somehow.

jsakalos
6 May 2010, 2:05 AM
Im guessing the overidden setValue function is activating the validation somehowWe can fix something that happens; no chance to fix what you think may happen.

JBarton
6 May 2010, 6:02 AM
We can fix something that happens; no chance to fix what you think may happen.

haha thanks, Mr Miyagi. No, client validation is definitely firing on the popcombos in my FormPanel when i load data into the form, I just don't know the cause - hence my post.

I will find a way to setup a showcase for you.