PDA

View Full Version : (Solved) Form submit problem with IE (all verions)



sydnic
14 May 2010, 7:57 AM
When I submit a form IE always fails with the error "Object doesn't support this property or method". There are no problems in Firefox, Opera, Safari or Chrome. Only IE reports errors

This is driving me nuts - I have been working with this for over a week and can't find a solution.

I am using the latest version of ExtJS and have checked my code for silly syntax errors. Perhaps somebody can find something I am missing.!

Using ext-all-debug.js the error occurs on line 732. variable 'n' is a object, and varable 'attr' has the value "success". Variable 'n' does not have the property getAttribute() and this appears to be the cause of the problem.

I don't know what ExtJS is doing here, so I am not is a position to fix this.

The submit always works and the server always returns the correct response. All the parameter values in the submit are correct. Any errors detected by the server are returned in the correct format and the XmlErrorReader is working perfectly.

This problem occurs only when the submission completes succesfully.

In the code there is a call back function defined for a sucessfull submit. I can comment this out - it makes no difference.

The system is complex and part of an ERP/Job costing application. I have included the relevant code:
I have concluded that the problem occurs AFTER the form has been submitted, and BEFORE any call back function is invoked. I don't understand what is happening between the submit and the call back back function.

This is my function for editing jobs, I have highlighted the code where the submit takes place. Any help would be greatly appreciated.:



// Edit/copy/create/display job
// Uses current job defined in joblist plus param opt to define function required
function edtJob(t,opt){
// Initial variables
var pageTitle; var btntxt; var jnum = 0; var inum = 0; var dnum = 0; var hb = true;
var jbdta = t.currentRecord.data;
var curCust = jbdta.JHCUST; var curCustDesc = jbdta.CUSDESC;
var curDiv = jbdta.JBHDIV;
var curCact = jbdta.JBHCACT;
var curDlvAdr = jbdta.JBHDLVADR;
var sbmurl;
switch(opt){
case jcsvar.add:
pageTitle = 'Create Job';btntxt = 'Create';sbmurl = 'jcJobBookJ?opt=' + 101;hb = false;
break;
case jcsvar.edit:
pageTitle = 'Edit Job ' + t.currentJob;btntxt = 'Change Job ' + t.currentJob;sbmurl = 'jcJobBookJ?opt=' + 104;jnum = t.currentJob;inum = dnum = 1;hb = false;
break;
case jcsvar.copy:
pageTitle = btntxt = 'Copy Job ' + t.currentJob;sbmurl = 'jcJobBookJ?opt=' + 101;hb = false;
break;
case jcsvar.display:
pageTitle = btntxt = 'Display Job ' + t.currentJob;sbmurl = 'jcJobBookJ?opt=' + 0;jnum = t.currentJob;inum = dnum = 1;
break;
};
// Define the display fields
var jobdate = new Ext.ccs.jc.form.JobDateField({fieldRequired:true,readOnly:hb,name:'JBHODAT'})
var delivdate = new Ext.ccs.jc.form.DeliveryDateField({fieldRequired:true,readOnly:hb,name:'JBDDATE'})
var customer = new Ext.ccs.jc.form.CustCombo({fieldRequired:true,readOnly:hb,name:'JBHCUST'});
var division = new Ext.ccs.jc.form.DivCombo({fieldRequired:true,readOnly:hb,name:'JBHDIV'});
var qty = new Ext.ccs.form.IntegerField({fieldLabel:'Quantity',readOnly:hb,fieldRequired:true,name:'JBIQOR',maxLength:7});
var jobtxt = new Ext.ccs.jc.form.JobTextField({fieldRequired:true,readOnly:hb,name:'JBHFDES'});
var wrktxt = new Ext.ccs.jc.form.JobWorkTextField({fieldRequired:true,readOnly:hb,name:'JBHSDES'});
var stxt = new Ext.ccs.jc.form.JobSearchTextField({readOnly:hb,name:'JBHSEAR'});
var cact = new Ext.ccs.jc.form.ContactsCombo({fieldRequired:true,readOnly:hb,name:'JBHCACT'});
var dlvadr = new Ext.ccs.jc.form.AddressCombo({fieldLabel:'Dft. deliv. address',fieldRequired:true,readOnly:hb,name:'JBHDLVADR'});
var prce = new Ext.ccs.form.NumberField({fieldLabel:'Selling Price',readOnly:hb,name:'JBISPRC',maxLength:9,allowNegative:false,renderer:decPosTo2});
var cono = new Ext.ccs.jc.form.CustomerOrderNumberField({fieldRequired:true,readOnly:hb,name:'JBICORD'});
var cdno = new Ext.ccs.jc.form.CustomerDrawingNumberField({fieldRequired:true,readOnly:hb,name:'JBVCDRWNO'});
var cdnorev = new Ext.ccs.jc.form.CustomerDrawingNumberRvnField({readOnly:hb,name:'JBVCDRWRVN'});
var conolin = new Ext.ccs.form.IntegerField({fieldLabel:'Order Line No.',readOnly:hb,name:'JBVCORDL',maxLength:3});
var cpno = new Ext.ccs.jc.form.CustomerPartNumberField({readOnly:hb,name:'JBVCPNO'});
var cpnorev = new Ext.ccs.jc.form.CustomerPartNumberRvnField({readOnly:hb,name:'JBVCPNORVN'});
var csno = new Ext.ccs.jc.form.CustomerSerialNumberField({readOnly:hb,name:'JBVCSRLNO'});
var crno = new Ext.ccs.jc.form.CustomerReqNumberField({readOnly:hb,name:'JBVREQNO'});
var msi = new Ext.ccs.form.Checkbox({readOnly:hb,fieldLabel:'Is Material Supplied Internally?',name:'JBVBMSRC'});
var msc = new Ext.ccs.form.Checkbox({readOnly:hb,fieldLabel:'Is Material Supplied By Customer?',name:'JBVCMSRC'});
var mrcv = new Ext.ccs.form.Checkbox({readOnly:hb,fieldLabel:'Has Material Been Received?',name:'JBVMRCV'});
var mloc = new Ext.ccs.form.TextField({readOnly:hb,fieldLabel:'Location of Material',name:'JBVMLOC'});
var mrdat = new Ext.ccs.form.DateField({readOnly:hb,fieldLabel:'Date Material Received',name:'JBVMTMSTP'})
var ljob = new Ext.ccs.jc.form.JobNoField({readOnly:hb,fieldLabel:'Previous Job',name:'JBHLJNO'});
var dfndiv = new Ext.Button({text:'New Division (F6)',disabled:true,minWidth:150,handler:function(){var nd = new Divisions(); nd.init('Customer',curCust,curCustDesc); nd.crtDiv(division.store,'reloadDivisionCombo');}});
var dfnadr = new Ext.Button({text:'New Address (F7)',disabled:true,minWidth:150,handler:function(){var nd = new Addresses(); nd.init('Customer',curCust,curCustDesc); nd.setTmpDiv(curDiv); nd.crtAdr(dlvadr.store,'reloadAddressCombo');}});
var dfncnt = new Ext.Button({text:'New Contact (F8)',disabled:true,minWidth:150,handler:function(){var nd = new Contacts(); nd.init('Customer',curCust,curCustDesc); nd.setTmpAdr(gCurAdr); nd.crtCnt(cact.store,'reloadContactCombo');}});
var pgrp = new Ext.ccs.form.NumberField({fieldLabel:'Product Group',readOnly:true,name:'JBIPGRP',hidden:true,hideLabel:true});
var prod = new Ext.ccs.form.NumberField({fieldLabel:'Product',readOnly:true,name:'JBIPROD',hidden:true,hideLabel:true});
// Field sets
var jobFldSet = {xtype:'fieldset',title:'Job Details',autoHeight:true,collapsible:false,items:[jobdate,delivdate,qty,jobtxt,wrktxt,stxt,ljob,prce,pgrp,prod]};
var cstFldSet = {xtype:'fieldset',title:'Customer Details',autoHeight:true,collapsible:false,items:[customer,division,dlvadr,cact,cono,conolin,cdno,cdnorev,cpno,cpnorev,csno,crno]};
var matFldSet = {xtype:'fieldset',title:'Material Details',autoHeight:true,collapsible:false,items:[msi,msc,mrcv,mloc,mrdat]};
// Add listeners and loaders for data fields
customer.on('select',function(cb,r,idx){
curCust = r.get('XPCCDE');
curCustDesc = r.get('DESC');
dfndiv.enable();
division.reset();
division.store.load({params:{code:curCust}});
});
division.store.on('load',function(s,ra,o){
if (ra[0]) {if (!curDiv) {curDiv = ra[0].get('SODIV');};};
division.setValue(curDiv);
dfnadr.enable();
dlvadr.reset();
dlvadr.store.load({params:{code:curCust,type:'4',division:curDiv}});
});
division.on('change',function(cb,nv,ov){
curDiv = nv;
dlvadr.reset();
dlvadr.store.load({params:{code:curCust,type:'4',division:curDiv}});
dfnadr.enable();
});
division.on('select',function(cb,r,idx){
curDiv = r.get('SODIV');
dlvadr.reset();
dlvadr.store.load({params:{code:curCust,type:'4',division:curDiv}});
dfnadr.enable();
});
cact.store.on('load',function(s,ra,o){
if (!curCact) {curCact = ra[0].get('SRSEQ');};
cact.setValue(curCact);
});
dlvadr.on('select',function(cb,r,idx){dfncnt.enable(); curDlvAdr = r.get('SPSEQ');cact.reset();cact.store.load({params:{code:curCust,addr:curDlvAdr}});});
dlvadr.on('change',function(cb,nv,ov){dfncnt.enable(); curDlvAdr = nv;cact.reset();cact.store.load({params:{code:curCust,addr:curDlvAdr}});});
dlvadr.store.on('load',function(s,ra,o){
if (ra[0]) {if (!curDlvAdr) {curDlvAdr = ra[0].get('SPSEQ')};};
dlvadr.setValue(curDlvAdr);
cact.reset();
cact.store.load({params:{code:curCust,addr:curDlvAdr}});
dfncnt.enable();
});
// Define form and display window
var frmreader = new Ext.data.JsonReader({root:'rows',id:'frmreader',successProperty:'success'},['JBHODAT','JBDDATE','JBHCUST','JBIQOR','JBHFDES','JBHSDES','JBHSEAR','JBHLJNO','JBISPRC','JBICORD','JBIQDL','JBIPGRP','JBIPROD','JBVCDRWNO','JBVCDRWRVN','JBVCORDL','JBVCPNO','JBVCPNORVN','JBVCSRLNO','JBVREQNO','JBVBMSRC','JBVCMSRC','JBVMRCV','JBVMLOC','JBVMTMSTP','JBHCACT','JBHDIV','JBHDLVADR']);
var edtfrm = new Ext.ccs.form.FormPanel({
title:pageTitle,
labelWidth:100,
shadow:true,
layout:'column',
reader: frmreader,
url:sbmurl,
errorReader: new Ext.form.XmlErrorReader(),
items:[
{columnWidth:.34,layout:'form',items:[jobFldSet]},
{columnWidth:.34,layout:'form',items:[cstFldSet]},
{columnWidth:.32,layout:'form',items:[matFldSet]}
]
});
var edtwin = new Ext.Window({layout:'form',modal:true,width:1220,buttonAlign:'left',closeAction:'close',items:edtfrm,buttons:[
dfndiv,
dfnadr,
dfncnt,
'->',
{text: btntxt, hidden: hb, disabled: hb, handler: function() {
edtfrm.getForm().submit({
method: 'POST',
success: function(){km.disable();getMsgResult();},
waitMsg: 'Saving Data...',
params: {
jobno: jnum,
itmno: inum,
dlvno: dnum,
JobDate: (jobdate.getValue()) ? jobdate.getValue().format(jcsvar.iso):' ',
DelivDate: (delivdate.getValue()) ? delivdate.getValue().format(jcsvar.iso):' ',
Customer: customer.getValue(),
jbhdiv: division.getValue(),
Qty: qty.getValue(),
JobTxt: jobtxt.getValue(),
WrkTxt: wrktxt.getValue(),
Stxt: stxt.getValue(),
jbhcact: cact.getValue(),
jbhdlvadr: dlvadr.getValue(),
Prce: prce.getValue(),
Cono: cono.getValue(),
Cdno: cdno.getValue(),
CdnoRev: cdnorev.getValue(),
ConoLin: conolin.getValue(),
Cpno: cpno.getValue(),
CpnoRev: cpnorev.getValue(),
Csno: csno.getValue(),
Crno: crno.getValue(),
Msi:(msi.getValue() == true) ? '1' : '0',
Msc:(msc.getValue() == true) ? '1' : '0',
Mrcv:(mrcv.getValue() == true) ? '1' : '0',
Mloc:mloc.getValue(),
Mrdat:(mrdat.getValue()) ? mrdat.getValue().format(jcsvar.iso) : ' ',
LJob: ljob.getValue(),
pgrp:pgrp.getValue(),
prod:prod.getValue()
}});
}},
{text: 'Cancel (F12)', handler: function() { edtwin.close(); actobj = null;}}
],
listeners:{
'show':function(){
focusObj(jobdate);
kms.pushKeyMap(km);
km = new Ext.KeyMap(document,[
{key:Ext.EventObject.F6,fn:function(k,e){e.stopEvent();edtwin.buttons[0].handler();},scope:this},
{key:Ext.EventObject.F7,fn:function(k,e){e.stopEvent();edtwin.buttons[1].handler();},scope:this},
{key:Ext.EventObject.F8,fn:function(k,e){e.stopEvent();edtwin.buttons[2].handler();},scope:this},
{key:Ext.EventObject.ENTER,fn:function(k,e){e.stopEvent();edtwin.buttons[4].handler();},scope:this},
{key:Ext.EventObject.F12,fn:function(k,e){e.stopEvent();edtwin.buttons[5].handler();},scope:this}
]);
},
'close':function(){km.disable();km = kms.popKeyMap();}
}
});
// Load data depending upon option selected
switch(opt){
case jcsvar.display:
edtfrm.getForm().load({url:'jcJobBookJ?opt=103',method:'GET',waitMsg:'Loading...',params:{jobno:t.currentJob}});
break;
case jcsvar.edit:
edtfrm.getForm().load({url:'jcJobBookJ?opt=103',method:'GET',waitMsg:'Loading...',params:{jobno:t.currentJob}});
break;
case jcsvar.copy:
edtfrm.getForm().load({url:'jcJobBookJ?opt=103',method:'GET',waitMsg:'Loading...',params:{jobno:t.currentJob}});
ljob.setValue(t.currentJob);
break;
};
// Set initial values and show window
actobj = [{obj:edtwin,act:'close'},{obj:jl,act:'refresh'}];
edtwin.show();
jobdate.setValue(new Date());
delivdate.setValue(new Date());
prce.setValue(0.00);
};

CrazyEnigma
14 May 2010, 7:31 PM
Too much code.

Have you tried narrowing down your submit? Seeing where the submit has broken down. Or attaching your server process to your VS? Seeing if it has completed the response?

Is your response returning a success: true?

sydnic
15 May 2010, 1:10 PM
Thanks for the reply,

Sorry about the code - it is a complex and large system. It works at my client's site, but not at mine. I don't know why but it must be something to do with IE.

The submit completes without error but does not return anything. I have tried a return value with success:true, but this causes ALL browsers to fail, and makes no difference to IE. If an error is detected on the submit, then XML is returned with success:false and and error messages for the XMLErrorReader to highlight the error flag for the appropriate field.

The software always stops at line 732 of ext-all-debug.js because variable 'n' does not have the property getAttribute(). I can only assume that 'n' has something to do with the response object.

I have created simpler software that experiences exactly the same problem. This an entire HTML file, I hope it is not too much code.



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
<TITLE>iBooks</TITLE>
<link rel="stylesheet" type="text/css" href="scripts/extjs/resources/css/ext-all.css" />
<SCRIPT SRC="scripts/extjs/adapter/ext/ext-base.js"></SCRIPT>
<SCRIPT SRC="scripts/extjs/ext-all-debug.js"></SCRIPT>
<SCRIPT SRC="scripts/extjs/src/locale/ext-lang-en_GB.js"></SCRIPT>
<script type="text/javascript">
Ext.namespace('Ext.ccs');
Ext.namespace('Ext.ccs.form');
var ccsUtilFunctions = {}; var jcsvar = {}; var actobj;
ccsUtilFunctions.setFieldVisible=function(fld,vis){if(vis==true){fld.enable();fld.show();fld.getEl().up('.x-form-item').setDisplayed(true)}else{fld.disable();fld.hide();fld.getEl().up('.x-form-item').setDisplayed(false)}};
ccsUtilFunctions.set_tt=function(){this.el.dom.qtip=this.tooltip.text;this.el.dom.qtitle=this.tooltip.title;Ext.QuickTips.enable()};
ccsUtilFunctions.set_field_cfg=function(config,label,tooltipText){var lbl=label;c=config;lbl=(!c.fieldLabel)?lbl:c.fieldLabel;if(c.preText)lbl=c.preText+' '+lbl;if(c.postText)lbl+=' '+c.postText;if(!c.fieldRequired)c.fieldRequired=false;c.fieldLabel=(c.fieldRequired==true)?jcsvar.textRequiredIndicator+lbl:lbl;var tooltip=(!c.tooltip)?{title:lbl,text:tooltipText}:c.tooltip;if(c.tooltipText){tooltip.text=c.tooltipText;if(c.fieldRequired==true)tooltip.text+=jcsvar.textRequiredTooltip}c.tooltip=tooltip;var lstnr=!c.listeners?{'render':ccsUtilFunctions.set_tt}:c.listeners;if(!lstnr.render)lstnr.render=ccsUtilFunctions.set_tt;c.listeners=lstnr;return c};
jcsvar.textRequiredIndicator='<font face="Arial" color="#FF0000">*</font>';jcsvar.datfmt='d/m/Y';
Ext.ccs.form.TextField=function(config){var c={name:'textField'};if(config)c=config;var l=c.fieldLabel;c=ccsUtilFunctions.set_field_cfg(c,'Text Field');Ext.ccs.form.TextField.superclass.constructor.call(this,Ext.apply(c,{name:!c.name?'textField':c.name,width:!c.width?250:c.width,enableKeyEvents:!c.enableKeyEvents?true:c.enableKeyEvents,selectOnFocus:true,label:l}))};Ext.extend(Ext.ccs.form.TextField,Ext.form.TextField,{setRequired:function(val){this.fieldLabel=(val==true)?ccsUtilVar.textRequiredIndicator+this.label:this.label}});Ext.reg('ccsTextField',Ext.ccs.form.TextField);
Ext.ccs.form.FormPanel=function(config){var c={name:'ccsFormPanel'};if(config)c=config;Ext.ccs.form.FormPanel.superclass.constructor.call(this,Ext.apply(c,{frame:!c.frame?true:c.frame,region:!c.region?'center':c.region,labelAlign:!c.labelAlign?'left':c.labelAlign,labelWidth:!c.labelWidth?150:c.labelWidth,autoHeight:!c.autoHeight?true:c.autoHeight}))};Ext.extend(Ext.ccs.form.FormPanel,Ext.FormPanel);Ext.reg('ccsFormPanel',Ext.ccs.form.FormPanel);
// XML error reader class for XML forms
Ext.form.XmlErrorReader = function(){
Ext.form.XmlErrorReader.superclass.constructor.call(this,{record:'field',success:'@success'},['id', 'msg']);actobj = null;};
Ext.extend(Ext.form.XmlErrorReader, Ext.data.XmlReader);
Ext.onReady(function(){
Ext.QuickTips.enable();
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';
var uid = new Ext.ccs.form.TextField({ fieldLabel: 'User ID', name: 'uid'});
var pwd = new Ext.ccs.form.TextField({ fieldLabel: 'Password', name: 'pwd', inputType: 'password' });
var lgfrm = new Ext.ccs.form.FormPanel({
title: 'Log On',
errorReader: new Ext.form.XmlErrorReader(),
items: [uid, pwd]
});
lgwin = new Ext.Window({
layout:'form',
modal:true,
width:500,
closeAction:'close',
items:lgfrm,
listeners:{'show':function(){uid.focus(true,500);}},
buttons:[
{text: 'Log On',
handler:function() {
lgfrm.getForm().submit({
url:'index?opt=1',
method: 'POST',
scope:this,
success:function(){lgwin.close();},
waitMsg: 'Logging On...',
params: {val1:uid.getValue(),val2:pwd.getValue()}
})
}
},
{text: 'Cancel', handler: function() { lgwin.close(); } }
]
});
lgwin.show();
});
</script>
<BODY>
</BODY>
</HTML>

sydnic
17 May 2010, 3:05 AM
I have found the solution to this problem -- it is the XMLErrorReader!!!! It would appear that ExtJS with IE is expecting a response in json format. This must be a bug in ExtJS.

I created a simple json error reader, based on the logic used for the XmlErrorReader:



Ext.form.JsonErrorReader = function(){
Ext.form.JsonErrorReader.superclass.constructor.call(this,{
root:'rows',
successProperty:'success'
},
['id','msg']
)
};
Ext.extend(Ext.form.JsonErrorReader,Ext.data.JsonReader);


This consumes json of the form

{success:false,rows:[
{id:'FieldName',msg:'This field is in error'},
{id:'AnotherName',msg:'Aother field in in error'}
]}

Where the 'id' is the name property of the field in error.

With the JsonErrorReader in place the server returns all responses in JSON with either success:true or success:false.

This means that ALL server responses MUST be changed fro XML to JSON, and ALL form submits must also be changed from an XmlErrorReader to a JsonErrorReader. In my case this is quite a big job.

I hope this helps anybody else with the same problem.

CrazyEnigma
17 May 2010, 10:19 AM
You may not have to change your back-end, with the exception of sending a success: true/false (<success>true/false</success>) somewhere in your XML. And the XMLReader, just has to determine where that success tag is.

I am not too sure, but read up on the XMLReader. I don't believe this should be a bug. If it is, you may want to file it under the bugs forum.

sydnic
17 May 2010, 12:44 PM
The problem with the XmlErrorReader is that any 'success:true' value returned causes all browsers to fail. I am certain this is because the form was originally loaded using JSON. I think the system is confused as to whether it should expect XML or JSON.

With other browsers a success is indicated by there being no return value. Any error data is transfered as XML. This works well, and in ExtJS 2.0 was not a problem.

This problem seems to have been introduced in ExtJS 3.x

The server has many programs, all of them compiled objects. I am talking to an IBM System I, programming in RPG. My expertise in JavaScript is limited. Fortunately, the server has an object oriented design, only a single message handling service program requires alteration. I also need change the corresponding JavaScript objects, about 60+ objects. Then the system needs to be tested. I should look at the object oriented nature of the JavaScript.

Time is money and I have already spent over a week on this issue, I can't affort more time. I can now move forward and will have all the changes competed tomorrow.