-
1 Apr 2010 9:11 AM #1
[solved]Ext.Direct load data in extended Form fails (scope issue)
[solved]Ext.Direct load data in extended Form fails (scope issue)
Hello,
when loading data into an extend form, i always get
(Note: this linenumber refers to ext 3.2.0 that has been released today - thank you :-))Code:this.form is undefined [Break on this error] this.form.afterAction(this, false); ext-all-debug.js (Zeile 65958)
Submit works just fine.
At that line, it seems that "this" point to the global window object instead to the form.
Before that happens - arround line 63138-63141 it looks good.
loadAction == "directload" and this == the form.PHP Code:load : function(options){
var loadAction = String.format('{0}load', this.api ? 'direct' : '');
this.doAction(loadAction, options);
return this;
},
Maybe this thread is related: http://www.extjs.com/forum/showthread.php?t=86826
Here the code - am i doing something wrong - is this an ext scope issue?
Any help / hint is very much appreciated - Thank youPHP Code:Ext.ns('Ext.app');
Ext.app.AddHostForm = Ext.extend(Ext.form.FormPanel, {
bodyStyle: 'padding:10px;'
,autoScroll:true
,initComponent: function(){
var config = {
api: {
load: rpc.Hosts.get
,submit: rpc.Hosts.addHost
}
,defaultType: 'textfield'
,items: [{
fieldLabel: 'Hostname'
,name: 'hostname'
,allowBlank:false
}
,{
fieldLabel: 'User Name'
,name: 'username'
,allowBlank:false
}
,{
fieldLabel: 'Password'
,inputType: 'password'
,name: 'password'
,allowBlank:false
}] // oe items
,buttons:[{
text:'Load'
,scope:this
,handler:this.onLoad
}
,{
text:'Submit'
,scope:this
,handler:this.onSubmit
}] // oe buttons
};
Ext.apply(this, config);
Ext.apply(this.initialConfig, config);
Ext.app.AddHostForm.superclass.initComponent.apply(this, arguments);
} // oe initComponent
// direct load handler
,onLoad: function() {
this.getForm().load({
params: {
id: 1
}
,success: function() {
console.log('load success');
}
,failure: function() {
console.log('load failure');
}
});
} // eo onLoad
// direct submit handler
,onSubmit: function() {
this.getForm().submit({
params: {id: 2}
,success: function() {
console.log('submit success');
}
,failure: function() {
console.log('submit failure');
}
});
} //eo onSubmit
});
Ext.reg('appaddhostform', Ext.app.AddHostForm);
-
1 Apr 2010 1:29 PM #2
vg Steffen
--------------------------------------
Release Manager of TYPO3 4.5
energlobe.de - german online magazine
-
1 Apr 2010 1:59 PM #3
Steffen thank you - but i still need a bit more enlightment, even after reading your thread.
From Ext Form.js:
i see i need to have set initialConfig. But this is what i have done in my codePHP Code:// private
createForm : function(){
var config = Ext.applyIf({listeners: {}}, this.initialConfig);
return new Ext.form.BasicForm(null, config);
},

also - removing the api definition from initComponent and adding an onRender method does not help:PHP Code:Ext.apply(this, config);
Ext.apply(this.initialConfig, config);
Ext.app.AddHostForm.superclass.initComponent.apply(this, arguments);
PHP Code:// does not work neither - independent wether to call superclass before or after Ext.apply
,onRender: function() {
//Ext.app.AddHostForm.superclass.onRender.apply(this, arguments);
Ext.apply(this.getForm(),{
api: {
load: rpc.Hosts.get
,submit: rpc.Hosts.addHost
}
,paramsAsHash: false
});
Ext.app.AddHostForm.superclass.onRender.apply(this, arguments);
}
-
2 Apr 2010 7:02 AM #4
the latest is the one i use in my forms. Are you sure you have proper formHandler set? Is there a request?
here is a working formPanel i use:
PHP Code:Ext.ns('TYPO3.EM');
TYPO3.EM.TerUpload = Ext.extend(Ext.form.FormPanel, {
border:false,
recordData: null,
initComponent:function() {
Ext.apply(this, {
itemId: 'extUploadForm',
height: 340,
defaultType: 'textfield',
defaults: {width: 350},
items: [{
fieldLabel: 'Repository Username',
name: 'fe_u'
}, {
fieldLabel: 'Repository Username',
inputType: 'password',
name: 'fe_p'
}, {
fieldLabel: 'Changelog for upload',
xtype: 'textarea',
height: 150,
name: 'uploadcomment'
}, {
xtype: 'radiogroup',
fieldLabel: 'New Version',
itemCls: 'x-check-group-alt',
columns: 1,
items: [
{boxLabel: 'New bugfix version (latest x.x.<strong><span class="typo3-red">x+1</span></strong>)', name: 'newversion', inputValue: 'new_dev',checked: true},
{boxLabel: 'New sub version (latest x.<strong><span class="typo3-red">x+1</span></strong>.0)', name: 'newversion', inputValue: 'new_sub'},
{boxLabel: 'New main version (latest <strong><span class="typo3-red">x+1</span></strong>.0.0)', name: 'newversion', inputValue: 'new_main'}
]
}, {
xtype: 'button',
text: 'Upload extension',
scope: this,
handler: function() {
this.form.submit({
waitMsg : 'Sending data...',
success: function(form, action) {
TYPO3.Flashmessage.display(1,'TER Upload', 'Extension was uploaded to TER', 5);
form.reset();
},
failure: function(form, action) {
if (action.failureType === Ext.form.Action.CONNECT_FAILURE) {
TYPO3.Flashmessage.display(3, 'Error',
'Status:'+action.response.status+': '+
action.response.statusText, 5);
}
if (action.failureType === Ext.form.Action.SERVER_INVALID){
// server responded with success = false
TYPO3.Flashmessage.display(3, 'Invalid', action.result.errormsg, 5);
}
}
});
}
}],
listeners: {
activate: function(panel) {
}
},
scope: this
});
TYPO3.EM.TerUpload.superclass.initComponent.apply(this, arguments);
},
onRender: function() {
TYPO3.EM.TerUpload.superclass.onRender.apply(this, arguments);
Ext.apply(this.getForm(),{
api: {
load: TYPO3.EM.ExtDirect.loadUploadExtToTer,
submit: TYPO3.EM.ExtDirect.uploadExtToTer
},
paramsAsHash: false
});
this.form.load();
}
});
Ext.reg('terupload', TYPO3.EM.TerUpload);
vg Steffen
--------------------------------------
Release Manager of TYPO3 4.5
energlobe.de - german online magazine
-
2 Apr 2010 2:24 PM #5
Thank you very much steffen.
Well after some hours of debugging i finally got it running.
Ok first the fix - it looks pretty easy (set either paramsAsHash:true or paramOrder: ['id'])
Really simple once you know this.PHP Code:,initComponent: function(){
var config = {
api: {
load: rpc.Hosts.get
,submit: rpc.Hosts.addHost
}
//,paramOrder: ['id'] // really important! either this
,paramsAsHash: true // or this - otherwise error! this.form. ist not an object...
But why does it lead to such an error?
All we do is to define how params are sent during a load event using Ext.direct / "directload"?
We have some issues to think about:
a.) Where to put the api:{} and paramOrder/paramsAsHash properties?
b.) How to use paramOrder/paramsAsHash?
c.) Is there anything else important?
About a.)
This was the issue that steffen found/solved (But this was not the issue i faced)
"api" and "paramOrder/paramsAsHash" must be set in initComponent or in onRender/afterRender.
The reason for this is in Ext.FormPanel:
About b.)PHP Code:createForm : function(){
var config = Ext.applyIf({listeners: {}}, this.initialConfig);
return new Ext.form.BasicForm(null, config);
},
"paramOrder" or set "paramsAsHash:true" must be set. This is important!
The reason for this is that Ext.form.Action.DirectLoad.getParam() would return an empty array.
If both properties are set, "paramOrder" takes preference.
Have a look here:
getParams() also revels the "secret" of paramsAsHash. Basically (as the name implies) it defines how the called loadhandler in the backend gets the params: Either all params in one hash or as seperate params.PHP Code:getParams : function() {
var buf = [], o = {};
var bp = this.form.baseParams;
var p = this.options.params;
Ext.apply(o, p, bp);
var paramOrder = this.form.paramOrder;
if(paramOrder){
for(var i = 0, len = paramOrder.length; i < len; i++){
buf.push(o[paramOrder[i]]);
}
}else if(this.form.paramsAsHash){
buf.push(o);
}
return buf;
},
About c.)
Well, what happens if no param is specified or if both paramsAsHash/paramOrder is not set?
In this case one get the error i ran into.
But why?
The first step to the answer is again in Ext.form.Action.DirectLoad:
The first push would be the result of getParams().PHP Code:run : function(){
var args = this.getParams();
args.push(this.success, this);
this.form.api.load.apply(window, args);
},
But bc i had not set paramsAsHash/paramOrder, this was an empty array.
This leads to trouble in Ext.direct.RemotingProvider:
args should bePHP Code:doCall : function(c, m, args){
var data = null, hs = args[m.len], scope = args[m.len+1];
but wasCode:args[param, function, form]
However with m.len == 1Code:args[function, form]
became a mess.Code:hs = args[m.len], scope = args[m.len+1];
Summary:
- When using Ext.direct with a form - you must use either "paramsAsHash:true" or "paramOrder:['myparam']".
- When extending such a form, you must set those properties, along with "api" either in initComponent or on/afterRender.
Thanks for reading - I know this is quite a long post but i hope it helps others to get a better understanding.
Wolfgang
-
2 May 2010 1:30 AM #6
I still get the "this.processResponse is not a function" error, even though everything looks fine. I hope you can clarify the flow of the scope.Code:run : function(){ var args = this.getParams(); args.push(this.success, this); this.form.api.load.apply(window, args); },
Is "this" in args.push(this.success, this); the scope for "this.success" callback?
Do ExtDirect functions take a third param for the scope of the callback? For example: Products.getAll('ASC', callback, this)?
When i do: args.push(this.success.createDelegate(this), this); everything works the way it should be...
In the code above, the scope (in my case) is "Ext.form.Action.DirectLoad". After the server response is received and the success callback is invoked, the scope in the callback is "window". I think it should be the action scope
-
6 May 2010 12:36 AM #7
This is correct.After the server response is received and the success callback is invoked, the scope in the callback is "window". I think it should be the action scope
Can you show more code, especially the form?
-
18 Aug 2010 7:55 AM #8
-
22 Mar 2011 1:40 AM #9


Reply With Quote