PDA

View Full Version : Ext.Form load(url: '...') doesn't populate form



trbot
28 Jun 2007, 6:34 AM
Hi all,

I figured this question was different enough from my previous that it should be posted seperately.

My problem is that I can retrieve a well-formed JSON response from a JSP, and I can load it using AJAX properly into a page, (so I can see the JSON code) but I can't seem to make it populate my form.

I have named all form fields identically to fields in the JSON response, which in turn are named identically to the fields in my "Record" object that I reference with the form.

What I'm trying to figure out is, is there some form-field mapping step that I am missing? Is there anywhere I can pick up an example (or working copy) of a form being loaded via JSON? It seems to be significantly different from loading an XML file so the Ext docs aren't helping.

Form code:


/**
* DETAILS FORM
*/
var frmAjax = new Ext.form.Form({
labelAlign: 'top',
waitMsg: 'Busy...',
reader: new Ext.data.JsonReader({
successProperty: 'success',
root: 'rows',
id: 'AC_NR'
}, Ext.data.Record.create([
{ name: 'AC_NR', type: 'string' },
{ name: 'TRY_NR', type: 'int' }
]))
});

frmAjax.add(
new Ext.form.TextField({
fieldLabel: 'Account Number',
name: 'AC_NR',
disabled: true,
autoCreate: true
}),
new Ext.form.TextField({
fieldLabel: 'Territory Number',
name: 'TRY_NR',
disabled: true,
autoCreate: true
})
);

frmAjax.render('frmAjax');


JSON code:


{ 'rows': { 'AC_NR': '000000E572', 'TRY_NR': 166 }, 'success': true }


Form data-load code:


frmAjax.load({
url: 'jsonquery.jsp?form&id=AC_NR&q=70245803ZFPLLa%26KRhZa%3D5bdppbi9chil9%5Db%21yp%7BGxll%7BrFkr%29z%22QrNYSaR%5E&q0=' + Ext.get('cmbAccount').getValue(),
waitMsg:'Loading...'
});


As I mentioned, the query JSP does return the correct data, and the call to this frmAjax.load() is made, as I see the "Loading..." popup message. (It displays for a second, then closes).

Thanks to anyone that can help, I'm thoroughly stuck!

RutgerB
28 Jun 2007, 6:59 AM
I'm having the same problem here: json form (http://extjs.com/forum/showthread.php?t=8344&highlight=json+form)

trbot
28 Jun 2007, 7:44 AM
One thing I noticed common between our two problems, is that the actioncompleted events do not fire for the JSON versions!

This leads me to believe that when calling frm.load() it fails. I think our problem might be syntactic, but there are no examples of form-loads using JSON.. :\

EDIT: Confirmed. I added an actionfailed handler and it does fail. Now I'm wondering if there is any way to get the error that occurs. I hate not having FF/Firebug... If anyone knows how to extract any measure of usefulness from FB Lite that would probably help...

tryanDLS
28 Jun 2007, 7:48 AM
Set BPs in the Action class methods and step thru the response handling process to see how you your resonse string is being processed.

trbot
28 Jun 2007, 7:54 AM
I'm sorry if this sounds really dumb, but I'm trying to stay afloat..

When you say action class, are you referring to the call to the load function, or the load function in the actual ext-all-debug.js, or some other Ext classes, or the handler function...

And when you say I should set BPs, that sounds wonderful, but that sounds like I would need some sort of IDE to do that? I'm on win2k in a corp environment where I can't install firefox, so I'm -really- hoping there is something I can use to accomplish this... I've been looking for sure. MS script debugger is for xp only, the few others mentioned on this forum only seem to be for analysis of http req/resp cycle or other things that don't really apply to this case. I suppose I need something for JS debugging...

tryanDLS
28 Jun 2007, 8:05 AM
Yes I meant the Ext.form.Action class (action.js) which has subclasses for load and submit. If you don't have access to a real clientside debugger, you're going to be completely handcuffed when it comes to debugging - using alerts is not a viable solution. There are some other threads that discuss debuggers for IE. Also, if you include the ext-all-debug.js file, you can CTRL-SHIFT-Home when your page comes up to display the builtin Ext mini-debug console.

trbot
28 Jun 2007, 8:51 AM
Okay, well I downloaded MS Script Debugger and threw breakpoints on Ext.form.BasicForm:



load : function(options){
{BP} this.doAction('load', options);
},


I traced it through, and i'm a bit lost since it is an asynchronous process, I get bogged down stepping through presentation code and listeners (which are tied up displaying progress on the ajax request!), and can't pinpoint the location where it actually fails...

EDIT:
Scratch that, I dug a little further and BP'd Ext.form.Action


processResponse : function(response){
{BP} this.response = response;
if(!response.responseText){
return true;
}
this.result = this.handleResponse(response);
return this.result;
},

It enters handleResponse, skipping over the if block (this.form.reader does not eval to true?)


handleResponse : function(response){
if(this.form.reader){
var rs = this.form.reader.read(response);
var data = rs.records && rs.records[0] ? rs.records[0].data : null;
return {
success : rs.success,
data : data
};
}
return Ext.decode(response.responseText);
}

And enters Ext.decode()


this.decode = function(json){
return eval("(" + json + ')');
};

Which then evals this exact json:


(
{
'rows': { 'AC_NR': '0000199AV9', 'TRY_NR': 176 },
'success': true
}
)

This is then returned, back through this.decode, back through handleResponse, back through processResponse to fill variable this.result.

It finally winds up in the [[Ext.extend(Ext.form.Action.Load, Ext.form.Action,]] block as result.


success : function(response){
var result = this.processResponse(response);
if(result === true || !result.success || !result.data){
this.failureType = Ext.form.Action.LOAD_FAILURE; <== it enters this if block
this.form.afterAction(this, false);
return;
}
this.form.clearInvalid();
this.form.setValues(result.data);
this.form.afterAction(this, true);
},

It enters the fail if-block and returns, then my page's event handler for actionfailed is fired.

From here I'm not sure what I can do to gain more insight... I'm not sure how to ascertain what content the variable for result should contain, or how to enumerate it's contents for viewing, and I'm also not sure what form my reader should take, although I will experiment with readers, stepping through the blocks again...

EDIT:
Reviewing the flow of data, perhaps it is encountering a problem Ext.decode()'ing the JSON since it contains 'rows': {}, success: true... I am going to try removing the nesting around the inner properties 'AC_NR', 'TRY_NR'...

EDIT:
Okay, that's not the issue. I restructured the test JSON to the form:


{ 'AC_NR': '00000R676W', 'TRY_NR': 166, 'success': true }

And it's still no go. Enters the same if (fail) block.

trbot
28 Jun 2007, 10:07 AM
I got it working!

It turns out that it needs three properties to function.

root
successProperty
id


Additionally, you must enclose JSON row info in an array as this example illustrates. (even if it's a single row for a form!)


{ 'rows': [{ 'AC_NR': '0000199A0E', 'TRY_NR': 176 }], 'success': true }

The reason for this is that in the [[Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {]] : readRecords code block it uses array length to determine number of rows to pull. If root is not an array, root.length will be undefined. (It is assumed to be an array)

The final (working) code for the form is:


/**
* DETAILS FORM
*/
var frmAjax = new Ext.form.Form({
labelAlign: 'top',
waitMsg: 'Busy...',
reader: new Ext.data.JsonReader({
successProperty: 'success',
root: 'rows',
id: 'AC_NR'
}, Ext.data.Record.create([
{ name: 'AC_NR', type: 'string' },
{ name: 'TRY_NR', type: 'int' }
]))
});

frmAjax.add(
new Ext.form.TextField({
fieldLabel: 'Account Number',
name: 'AC_NR'
}),
new Ext.form.TextField({
fieldLabel: 'Territory Number',
name: 'TRY_NR'
})
);

frmAjax.on({
actioncomplete: function(form, action) {
},
actionfailed: function(form, action) {
alert('Failed action on form...');
}
});

frmAjax.render('frmAjax');

The code to populate the form from the JSON response is:


frmAjax.load({
url: 'jsonquery.jsp?form&id=AC_NR&q=70245803ZFPLLa%26KRhZa%3D5bdppbi9chil9%5Db%21yp%7BGxll%7BrFkr%29z%22QrNYSaR%5E&q0=' + Ext.get('cmbAccount').getValue(),
waitMsg:'Loading...'
});

(The JSON response from this JSP is the string quoted above.)

Hopefully this helps someone else!

Ps. Thanks Ryan for helping me sort this out and motivating me to get a (crappy but functional) local js debugger =]

anakonda8472
9 Mar 2008, 3:51 AM
hello!

It does not seem to be the correct data that are returned from the script.
I had the same problem and it's vers simple:

The "rows" contains an "array of arrays". Your "rows" is just a single array.
Put your row into an array and try it out!

CU

riocn
17 Apr 2008, 12:24 AM
that is so helpful ,this problem has been bothering me for quite a while ,but since I'm using the json-lib to convert bean to json
and the return result I got doesn't contain the "[ ]" .
have no idea how to deal with that.

riocn
17 Apr 2008, 12:55 AM
StringBuilder sb= new StringBuilder();
JSONObject obj1
obj.put("detail",array);
sb.append(obj);
response.getWriter().print(sb.toString());

After I changed the " obj.put("detail",array);" into "obj.put("detail",array);"
It works,