PDA

View Full Version : Form Submission problem with IE



giega
9 Oct 2009, 4:18 PM
Once again, FF is working beautifully, but IE7 (and 6) is giving me a syntax error. After debugging the js, error appears to be in ext-debug-all line 11527 return eval('(' + json + ')')

If I make database server return SUCCESS:true, then there is no error. However, form's success and failure callbacks do not work. My guess is I could rewrite the form submission to use Ajax.request. But I'd like to keep existing code...

I just don't get it why the error.

Here is a snippet of the code:


var associate_form = new Ext.FormPanel({
frame: true,
title: 'Associate Personnel',
autoWidth: true,
items: [empselect,binID,empDetail],
buttons: [
{
text: 'Associate as Primary',
handler: function(){
associate_form.getForm().submit({
url: '<cfoutput>#xfa.BilletsComponent#?method=AssociatePersonToBillet&action=primary</cfoutput>',
waitMsg: 'Sending data...',
success: function(f,a) {
Ext.Msg.alert('Success', 'Person associated as primary');
billet_DS.reload();
associate_form.getForm().reset();
associatewin.hide();
},
failure: function(f,a) {
if (a.failureType === Ext.form.Action.CONNECT_FAILURE){
Ext.Msg.alert('Failure', 'Server reported:'+a.response.status+' '+a.response.statusText);
}
if (a.failureType === Ext.form.Action.SERVER_INVALID){
Ext.Msg.alert('Warning', a.result.errormsg);
}
}
});
}
}

Condor
10 Oct 2009, 4:02 AM
What exactly is your server returning?

It should be returning:

{succes: true}
or

{success: false, errors: {field1: 'Invalid', field2: 'Also invalid'}}

(preferably with Content-type set to application/json)

giega
11 Oct 2009, 7:41 AM
At this time server is not returning anything at all. And that's when I get syntax error only in IE. If I make server return
{"SUCCESS":true}then I get no error. However, that's when my success callback is not being called, it does not execute at all. But form is submitted successfully and database is updated.

I was reading about differences between form submission methods.
http://www.extjs.com/learn/Ext_FAQ_Forms#How_are_responses_handled_when_using_forms_versus_say_ajax_requests.3F (http://www.extjs.com/forum/../learn/Ext_FAQ_Forms#How_are_responses_handled_when_using_forms_versus_say_ajax_requests.3F)
To my understanding only Ajax.request expects {"SUCCESS":true}.

I inspected the form and action variables (f,a) in FireBug after performing Form.Submit:

action.response.status = 200
action.response.statusText = "OK"
Both Success and Failure callback work as expected in FF.

Now I make database server return (actual copy paste of the return)
{"SUCCESS":true}
FireBug console does not report anything to console as the Success and Failure callbacks are not being called at all. But form is submitted successfully and database is updated.

I feel like I could be overlooking something simple, but I can't put my finger on it....

giega
11 Oct 2009, 8:02 AM
Also, just looked at the ExtJs Documentation under Form.Action failureType.
There is a complete snippet of form submission process. There is the following code for success:

success: function(form, action){
// server responded with success = true
var result = action.result;
}

Interesting thing is that action has no such property as result. I tried that,
action.result is undefined.

Condor
11 Oct 2009, 8:53 AM
If your server response doesn't conform to Ext's expectations, then you can use an errorReader.

The following error reader simply accepts every response:

errorReader: {
read: function(response){
return {
success: true,
};
}
}

giega
11 Oct 2009, 10:32 AM
As always, I appreciate your help, Condor.

I have tried errorReader, but still no luck.

I have ColdFusion server, that actually returns JSON formatted string as

{"SUCCESS":true}

I have tried to return string as

{success:true}

but no luck so far. What format would be correct?

errorReader does not help much because it's not being called just like success or failure callbacks.

There are no errors on the database side.

Condor
11 Oct 2009, 12:40 PM
Did you try:

errorReader: new Ext.data.JsonReader({
successProperty: 'SUCCESS'
})

giega
11 Oct 2009, 1:40 PM
errorReader appears not being called. Unless I am doing it totally wrong....



{
text: 'Associate as Primary',
id: 'associatePrimary',
handler: function(){
associate_form.getForm().submit({
url: '<cfoutput>#xfa.BilletsComponent#?method=AssociatePersonToBillet&action=primary</cfoutput>',
waitTitle: 'Please wait',
waitMsg: 'Sending data...',
errorReader: {
read: function(response){
var data = Ext.decode(response.responseText);
console.log(data);
return data.message;
}
},
success: function(f,a) {
Ext.Msg.alert('Success', 'Person associated as primary');
billet_DS.reload();
//f.reset();
empDetail.updateDetail('');
associatewin.hide();
},
failure: function(f,a) {
if (a.failureType === Ext.form.Action.CONNECT_FAILURE){
Ext.Msg.alert('Failure', 'Server reported:'+a.response.status+' '+a.response.statusText);
}
if (a.failureType === Ext.form.Action.SERVER_INVALID){
Ext.Msg.alert('Warning', a.result.errormsg);
}
}
});
}
},
{
text: 'Associate Non Primary',
formBind: true,
id: 'associateNonPrimary',
handler: function(){
associate_form.getForm().submit({
url: '<cfoutput>#xfa.BilletsComponent#?method=AssociatePersonToBillet&action=nonprimary</cfoutput>',
waitTitle: 'Please wait',
waitMsg: 'Sending data...',
errorReader: new Ext.data.JsonReader({
successProperty: 'SUCCESS'
}),
success: function(f,a){
Ext.Msg.alert('Success', 'Person associated');
billet_DS.reload();
//f.reset();
empDetail.updateDetail('');
associatewin.hide();
},
failure: function(f,a){
if (a.failureType === Ext.form.Action.CONNECT_FAILURE){
Ext.Msg.alert('Failure', 'Server reported:'+a.response.status+' '+a.response.statusText);
}
if (a.failureType === Ext.form.Action.SERVER_INVALID){
Ext.Msg.alert('Warning', a.result.errormsg);
}
}
});
}
}Here is firebug output:

For "primary" button

{"SUCCESS":true}For "non-primary" button (rigged an error on purpose)

{"SUCCESS":false,"MESSAGE":"There was a failure updating the information in the database."}In either case errorReader or callbacks did not seem to fire...

giega
11 Oct 2009, 2:50 PM
It seems as errorReader is not being triggered either. Unless I am doing something wrong with it...


{
text: 'Associate Non Primary',
formBind: true,
id: 'associateNonPrimary',
handler: function(){
associate_form.getForm().submit({
url: '<cfoutput>#xfa.BilletsComponent#?method=AssociatePersonToBillet&action=nonprimary</cfoutput>',
waitTitle: 'Please wait',
waitMsg: 'Sending data...',
errorReader: new Ext.data.JsonReader({
successProperty: 'SUCCESS'
}),
success: function(f,a){
Ext.Msg.alert('Success', 'Person associated');
billet_DS.reload();
//f.reset();
empDetail.updateDetail('');
associatewin.hide();
},
failure: function(f,a){
if (a.failureType === Ext.form.Action.CONNECT_FAILURE){
Ext.Msg.alert('Failure', 'Server reported:'+a.response.status+' '+a.response.statusText);
}
if (a.failureType === Ext.form.Action.SERVER_INVALID){
Ext.Msg.alert('Warning', a.result.errormsg);
}
}
});
}

I also researched and found your other post, and I have tried


{
text: 'Associate as Primary',
id: 'associatePrimary',
handler: function(){
associate_form.getForm().submit({
url: '<cfoutput>#xfa.BilletsComponent#?method=AssociatePersonToBillet&action=primary</cfoutput>',
waitTitle: 'Please wait',
waitMsg: 'Sending data...',
errorReader: {
read: function(response){
var data = Ext.decode(response.responseText);
console.log(data);
return data.message;
}
},
success: function(f,a) {
Ext.Msg.alert('Success', 'Person associated as primary');
billet_DS.reload();
//f.reset();
empDetail.updateDetail('');
associatewin.hide();
},
failure: function(f,a) {
if (a.failureType === Ext.form.Action.CONNECT_FAILURE){
Ext.Msg.alert('Failure', 'Server reported:'+a.response.status+' '+a.response.statusText);
}
if (a.failureType === Ext.form.Action.SERVER_INVALID){
Ext.Msg.alert('Warning', a.result.errormsg);
}
}
});
}
}Same results -> If server does not return anything - FF works perfectly, IE gives syntax error. If I return {"SUCCESS":true} callbacks are not called.....

Condor
11 Oct 2009, 8:47 PM
errorReader is a config option of the form, and not of the submit() method!

giega
12 Oct 2009, 8:02 AM
errorReader is a config option of the form, and not of the submit() method!

Doh! But by reading documentation it was hard to tell where it should go. Thanks, I will try that!

giega
12 Oct 2009, 3:01 PM
Condor, that did it! However, I am clueless why IE throws a fit... I did a console log from IE of the errorReader response, and everything seemed ok.


tId 4
status 200
statusText "OK"
getResponseHeader function()
getAllResponseHeaders function()
responseText ""
responseXML #document
argument undefinedThank you very much!

Condor
12 Oct 2009, 10:37 PM
responseText ""? Shouldn't that be "{SUCCESS:true}"?

giega
13 Oct 2009, 2:34 PM
Condor,

I forgot to return the success variable. NoW my errorReader response is


tId 6
status 200
statusText "OK"
getResponseHeader function()
getAllResponseHeaders function()
responseText "{"SUCCESS":true,"MESSAGE":"Update successful."}
responseXML #document
argument undefined

So far so good. My part of the for is as follows:


var associate_form = new Ext.FormPanel({
frame: true,
title: 'Associate Personnel',
autoWidth: true,
items: [empselect,binID,empDetail],
errorReader: {
read: function(response){
var data = Ext.decode(response.responseText);
//console.log(data.SUCCESS);
return data.SUCCESS;
}
},
buttons: [
{
text: 'Associate as Primary',
//id: 'associatePrimary',
handler: function(){
associate_form.getForm().submit({
url: '<cfoutput>#xfa.BilletsComponent#?method=AssociatePersonToBillet&action=primary</cfoutput>',
waitTitle: 'Please wait',
waitMsg: 'Sending data...',
success: function(f,a) {
Ext.Msg.alert('Success', 'Person associated as primary');
billet_DS.reload();
f.reset();
empDetail.updateDetail('');
associatewin.hide();
},
failure: function(f,a) {
if (a.failureType === Ext.form.Action.CONNECT_FAILURE){
Ext.Msg.alert('Failure', 'Server reported:'+a.response.status+' '+a.response.statusText);
}
if (a.failureType === Ext.form.Action.SERVER_INVALID){
Ext.Msg.alert('Warning', a.result.errormsg);
}
}
});
}
}

While with your help I was able to suppress the error message IE, I am back at the square one -- success and ailure callbacks are not called in both FF and IE.

I looked at the documentation BasicForm Submit method, and I can't find what is wrong with my code...

Condor
14 Oct 2009, 3:00 AM
The errorReader read() function needs to return an object with success, records and totalRecords properties (last 2 are optional).

This means the config should be:

errorReader: {
read: function(response){
var data = Ext.decode(response.responseText);
return {
success: data.SUCCESS,
records: [],
totalRecords: 0
}
}
}
or

errorReader: new Ext.data.JsonReader({
successProperty: 'SUCCESS'
})

giega
14 Oct 2009, 6:36 AM
Condor, as in my code above, I do have error reader that returns data.SUCCESS


errorReader: {
read: function(response){
var data = Ext.decode(response.responseText);
//console.log(data.SUCCESS);
return data.SUCCESS;
}
}

And server returns


{"SUCCESS":true,"MESSAGE":"Update successful."}
What do I have to do with the returned value? As soon as it returns success or failure status, Submit callbacks are not called.

I feel like we're running in circles....

Condor
14 Oct 2009, 7:22 AM
Are you sure this is the exact server response?

If it is not then it could be that the Ext.decode() throws an error (in which case neither success nor failure are called).

giega
14 Oct 2009, 7:51 AM
This is the exact server message. I pasted it right from the Firebug console.

Also, if in errorReader I log to console data.SUCCESS it outputs true or false.

giega
14 Oct 2009, 4:13 PM
I don't understand why IE has such difficulties with form.getForm.submit()....

Anyways, I have tried the Ajax.request method using



var conn = Ext.Ajax.request({
method: 'POST',
url: '<cfoutput>#xfa.BilletsComponent#?method=AssociatePersonToBillet&action=nonprimary</cfoutput>',
form: 'associate_form',
params: Ext.getCmp('associate_form').getForm().getFieldValues(),
success: function(response, options) {
var data = Ext.decode(response.responseText);
if (data.SUCCESS) {
Ext.MessageBox.alert('OK', response.responseText);
billet_DS.reload();
associate_form.getForm().reset();
empDetail.updateDetail('');
associatewin.hide();
}
else {
Ext.MessageBox.alert('ERROR', response.responseText);
}
},
failure: function(response, options) {
Ext.MessageBox.alert('Faulure Error', response.responseText);
}
})
And it all works beautifully. (But I am puzzled why I have to set params if I specify form: 'associate_form'...)

Condor
14 Oct 2009, 11:39 PM
It's because you need to specify the <form> element and not the FormPanel id, e.g.

form: Ext.getCmp('associate_form').getForm().getEl(),

ps. Still don't understand why submitting the form didn't work...

dulus
20 Oct 2009, 12:48 AM
I had similar problem, just add alert(json); before line 11527 (before return eval('(' + json + ')');) to see if json string is valid. My php backend function added some php warning there and that was reason of json parsing error.

giega
23 Oct 2009, 6:12 AM
Thanks for a tip, Dulus! I will try that!

And thanks to Condor for bearing with me on this issue and all the help. If I find the solution, I will post it here.

giega
24 Oct 2009, 9:24 AM
OK, finally was able to to spend more time and track down the issue. Apparently form submit success and failure callback functions expect JSON key variables in lower case. That means that
{"SUCCESS":true} is invalid. And
{"success":true} is valid. My response was in uppercase.

I am using ColdFusion 8 as backend server. In CF if you use SerializeJSON function or use returnformat="json", CF serializes the key names to all-uppercase JSON representations. I started reading more about this when I came across the comment made by Richard Davies at http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_s_03.html

He said that conversion to upper case is not entirely accurate. ColdFusion only uppercases key names created using "dot notation". Keys created using StructInsert(), array notation, or cfsavecontent retain whatever case was used the first time the key was created.

Aha!

In my function I had the following code:

<cffunction name="AssociatePerson" access="remote" output="false" returnformat="json">
<cfset var locVars = {} />
<cfset locVars.retVal.success = true />
<cfset locVars.retVal.message = "Update successful" />
<cftry>
<cftransaction>
<cfquery>
STUFF TO DO
</cfquery>
</cftransaction>
<cfcatch type="any">
<cfset locVars.retVal.success = false />
<cfset locVars.retVal.message = "There was a failure updating the information in the database." & cfcatch.Detail />
</cfcatch>
</cftry>
<cfreturn locVars.retVal>
</cffunction>My locVars.retVal was a dot notation, therefore was being converted to uppercase. So I changed my code to:

<cffunction name="AssociatePerson" access="remote" output="false" returnformat="json">
<cfset retValue = StructNew() />
<cfset StructInsert(retValue, "success", true) />
<cfset StructInsert(retValue, "message", "Update successful") />
<cftry>
<cftransaction>
<cfquery>
STUFF TO DO
</cfquery>
</cftransaction>
<cfcatch type="any">
<cfset StructUpdate(retValue, "success", false) />
<cfset StructUpdate(retValue, "message", "There was a failure updating the information in the database." & cfcatch.Detail) />
</cfcatch>
</cftry>
<cfreturn retValue>
</cffunction>Now my keys are not converted to uppercase and everything works like a charm.

Now I will have to be aware of this and properly format my return structures. Another workaround would be physically cfoutput {"success":true} and set cffunction output="true".

Another thing was that IE was always giving a syntax error in ext-all.js file at the line

doDecode=function(json){return eval("("+json+")")}if there was no success status response from server. IE was choking on the blank json string. To suppress the error, I made a small change in ext-all.js file - replaced above line with:

doDecode=function(json){return json==="" ? "" : eval("("+json+")")}Once again, thanks everyone for the help!