PDA

View Full Version : FormPanel Plugin: Overrides findField to include distant children



jerrybrown5
12 Oct 2007, 6:30 PM
I really like programming difficult stuff. Sometimes it almost doesn't even seem like work. :) However, I hate doing boring copy and paste programming. So when I realized how tedious it was to load a complicated form purely from javascript, it motivated me to try to improve the process.

Here is my solution using the following (alpha) code:



Ext.ux.DistantChildren={
registerDistantChild: function(child){
if (!this.distantChildren) { this.distantChildren={} }
this.distantChildren[ child.mapping || child.name || child.id ]=child;
},
unRegisterDistantChild: function(child){
delete this.distantChildren[ child.mapping || child.name || child.id ];
},
findFieldDistant: function(name){
var f;
if (this.findFieldOrginal){ f= this.findFieldOrginal(name) }
if (!f){
if (!this.distantChildren) { this.identifyDistantChildren() }
f=this.distantChildren[name];
}
return f;
},
identifyDistantChildren: function(scope){ /*Lazily using slow function recursion*/
if (!this.distantChildren) { this.distantChildren={} }
var items;
if (!scope){
scope=this; items=scope.itemsPanel
}else{
items=scope.items;
}
if (items && items.length){
for (var n=0; n < items.length; n++){
var item=items.items[n];
1;
if(item.isFormField){
this.registerDistantChild(item);
1;
}else{
if (item.items && item.items.length){
this.identifyDistantChildren(item)
}
}
}
}
}
};

Ext.ux.DistantChildren_plugin={
init:function(o){
if (o.form){
Ext.apply(o.form, Ext.ux.DistantChildren);
o.form.itemsPanel=o.items;
o.form.findFieldOrginal=o.form.findField;
o.form.findField=o.form.findFieldDistant;
}
}
};



Now the following drop dead simple code below will load all child fields from the same datastore--no matter their level.



var panel = new Ext.FormPanel({
plugins: Ext.ux.DistantChildren_plugin,
... place lots of framsets, tabs, with tons of fields at each level here ...
});
panel.form.loadRecord(datastore.getAt(0));



Easy enough and fast enough... Case closed....

Best regards,
Jerry Brown

ntulip
12 Oct 2007, 10:48 PM
Jerry,

Possible you could extend your sample by posting some code which actually adds items to FormPanel?

jerrybrown5
13 Oct 2007, 12:19 AM
Hopefully, I'll be able to create some good examples once I finish adding even more features to this. Coming soon:
* Value transformations (when a field in the db needs to be transformed when entering and leaving a form component)
* Language markups (will be a JSON stream apart from the form layout JSON stream that can override components especially including labels)

willydee
13 Oct 2007, 9:14 AM
* Value transformations (when a field in the db needs to be transformed when entering and leaving a form component)


Is this necessary? Just override the component's setValue() and getValue() methods, and you're done.

jerrybrown5
13 Oct 2007, 1:49 PM
By default the getValue and setValue methods at the component level are not meant to read and write to the datastore at all. By doing it this way you would be modifying the datastore on every little change, thus causing more problems than need be.

Plus, I don't think that this is the best way because of the extra tedious task of having to specify a datastore at each component or having to traverse up the containers (using ownerCt) from each component to the nearest form where a datastore would be defined. Of course you could leave a cookie trail at each level of container to the nearest form, but wouldn't that be adding more complexity than needed to achieve a similar level of speed?

Nevertheless, the way I did it works and it is probably the fastest (it traverses down from the form and only once) and the least cumbersome way (only a plugin), but as you mentioned this is not the only way.

What it does do is to provide the form class with a feature that it probably should have had all along, the mechanism to keep track of member components that are many levels deep.