xhrPost to Domino
Category xhrPost Domino Dojo
Bookmark :
Hi, David Bockes here. I've been working on a pretty extensive Dojo & Domino application. I have quite a few things that I should be blogging that have come out of this project that may be of interest, however I have been lax to do so. But, I'm going to try and correct that now. So, let's start with an issue that came up when trying to post a form back to the Domino server using xhrPost to save through Ajax.
I noticed that I would get inconsistant save results and that sometimes all the data in the form would save correctly and sometimes it would cutoff the data at a certain point. I then found that this would be based on whether or not data had been entered into fields that had been set as widgets (in this case the DateTextBox widget). The field had been defined as a widget by adding the following to the html attributes:
dojoType="dijit.form.DateTextBox" constraints="{datePattern: 'dd-MM-yyyy'}" required="true" promptMessage="dd/mm/yyyy" invalidMessage="Invalid date. Use dd/mm/yyyy format."
When sent to the browser, the outputted html for this field looks like this:
input name="ir_lh_Incident_Date" value="" dojoType="dijit.form.DateTextBox" constraints="{datePattern: 'dd-MM-yyyy'}" required="true" promptMessage="dd/mm/yyyy" invalidMessage="Invalid date. Use dd/mm/yyyy format." id="ir_lh_Incident_Date"
Note that in addition to a name, I also made sure to add an id in the properties box for this field (a good best practice for your Dojo stuff). Now, when this is parsed by dojo, the resulting html looks like this:
input id="ir_lh_Incident_Date" class="" type="text" autocomplete="off" dojoattachevent="onfocus,onblur:_onMouse,onkeyup,onkeypress:_onKeyPress" dojoattachpoint="textbox,focusNode" tabindex="0" value="" aaa:valuenow="" aaa:invalid="true" aaa:disabled="false" style=""
input type="text" value="" style="display: none;" name="ir_lh_Incident_Date"
Notice that two fields are created, one only has an id and no name and is the displayed version of the field that will show the date picker when clicked on. Right beneath that is a hidden version of the field that has a name but no id. When this form is submitted, the value from the display field is placed in the hidden field and is what gets saved into our document. However, the problem with the data save problems is due to the display version of the field. Domino is looking to match up the fields based on the name, not the id. The display version has no name, just an id. Now, you'd think that this would just get ignored, but it didn't.
I attempted to correct the issue in a WebQuerySave agent both by trying to strip out the no name fields or to only get the named fields and copy those. However this, since it's kinda a buggy problem, didn't work. So instead we took the approach of preventing the no name fields from being submitted in the first place. This was done by editing the Dojo source code and recompiling the custom Dojo build that I'm using.
To fix this, we have to use a "source" version of Dojo. A source version has the code that makes up the dojo.js and dijit.js split out into individual js files. In this case, we needed to edit the dojo\_base\xhr.js file. In there is a function called "formToObject" that is called as part of the xhrPost process. This function uses a dojo query to get only form elements on the page to submit to the server, leaving behind everything else. The key line for us is:
var iq = "input:not([type=file]) :not([type=submit]) :not([type=image]) :not([type=reset]) :not([type=button]), select, textarea";
This line builds the query to be used. Notice that it contains inclusions and exclusions (i.e., :not). The fix was to change the line to:
var iq = "input:not([type=file]) :not([type=submit]) :not([type=image]) :not([type=reset]) :not([type=button])[name], select, textarea";
Notice the inclusion of "[name]". This tells the query that the required item has to have a name attribute, if not, it is to be excluded. After making this change and recompiling the custom build, the problem was resolved. The no name fields were no longer submitted and all of the submitted data made it into the document in the back end. This resolution needs to be used in both Dojo 0.9 and 1.0. This was found to be a problem on R6 & R7 servers (I haven't tested on R8).
Bookmark :
Hi, David Bockes here. I've been working on a pretty extensive Dojo & Domino application. I have quite a few things that I should be blogging that have come out of this project that may be of interest, however I have been lax to do so. But, I'm going to try and correct that now. So, let's start with an issue that came up when trying to post a form back to the Domino server using xhrPost to save through Ajax.
I noticed that I would get inconsistant save results and that sometimes all the data in the form would save correctly and sometimes it would cutoff the data at a certain point. I then found that this would be based on whether or not data had been entered into fields that had been set as widgets (in this case the DateTextBox widget). The field had been defined as a widget by adding the following to the html attributes:
dojoType="dijit.form.DateTextBox" constraints="{datePattern: 'dd-MM-yyyy'}" required="true" promptMessage="dd/mm/yyyy" invalidMessage="Invalid date. Use dd/mm/yyyy format."
When sent to the browser, the outputted html for this field looks like this:
input name="ir_lh_Incident_Date" value="" dojoType="dijit.form.DateTextBox" constraints="{datePattern: 'dd-MM-yyyy'}" required="true" promptMessage="dd/mm/yyyy" invalidMessage="Invalid date. Use dd/mm/yyyy format." id="ir_lh_Incident_Date"
Note that in addition to a name, I also made sure to add an id in the properties box for this field (a good best practice for your Dojo stuff). Now, when this is parsed by dojo, the resulting html looks like this:
input id="ir_lh_Incident_Date" class="" type="text" autocomplete="off" dojoattachevent="onfocus,onblur:_onMouse,onkeyup,onkeypress:_onKeyPress" dojoattachpoint="textbox,focusNode" tabindex="0" value="" aaa:valuenow="" aaa:invalid="true" aaa:disabled="false" style=""
input type="text" value="" style="display: none;" name="ir_lh_Incident_Date"
Notice that two fields are created, one only has an id and no name and is the displayed version of the field that will show the date picker when clicked on. Right beneath that is a hidden version of the field that has a name but no id. When this form is submitted, the value from the display field is placed in the hidden field and is what gets saved into our document. However, the problem with the data save problems is due to the display version of the field. Domino is looking to match up the fields based on the name, not the id. The display version has no name, just an id. Now, you'd think that this would just get ignored, but it didn't.
I attempted to correct the issue in a WebQuerySave agent both by trying to strip out the no name fields or to only get the named fields and copy those. However this, since it's kinda a buggy problem, didn't work. So instead we took the approach of preventing the no name fields from being submitted in the first place. This was done by editing the Dojo source code and recompiling the custom Dojo build that I'm using.
To fix this, we have to use a "source" version of Dojo. A source version has the code that makes up the dojo.js and dijit.js split out into individual js files. In this case, we needed to edit the dojo\_base\xhr.js file. In there is a function called "formToObject" that is called as part of the xhrPost process. This function uses a dojo query to get only form elements on the page to submit to the server, leaving behind everything else. The key line for us is:
var iq = "input:not([type=file]) :not([type=submit]) :not([type=image]) :not([type=reset]) :not([type=button]), select, textarea";
This line builds the query to be used. Notice that it contains inclusions and exclusions (i.e., :not). The fix was to change the line to:
var iq = "input:not([type=file]) :not([type=submit]) :not([type=image]) :not([type=reset]) :not([type=button])[name], select, textarea";
Notice the inclusion of "[name]". This tells the query that the required item has to have a name attribute, if not, it is to be excluded. After making this change and recompiling the custom build, the problem was resolved. The no name fields were no longer submitted and all of the submitted data made it into the document in the back end. This resolution needs to be used in both Dojo 0.9 and 1.0. This was found to be a problem on R6 & R7 servers (I haven't tested on R8).


Comments
Posted by Bob At 09:33:16 PM On 11/29/2007 | - Website - |
Thanks for submitting this David. You and I have a lot to catch up on here.
Posted by Lance Spellman At 08:58:16 PM On 12/09/2007 | - Website - |
You can also prevent the 'nameless' INPUTs from being sent by using dojo.query():
dojo.query( "INPUT", frm ).filter(
function(inputnode) {
return (inputnode.name == '');
}
).orphan();
This removes all INPUT nodes with no name. Then submit the form normally using dojo.xhrPost().
Posted by L. Laanti At 11:10:50 PM On 12/11/2007 | - Website - |
Posted by Davd At 10:50:42 AM On 12/14/2007 | - Website - |
The Dojo XHRPost (version 1.0 at least) accepts also form nodes. I am using this in my application:
var kw = { url: frm.action,
load: function (data) {
targetPane.setContent(data);
},
error: function(data) {
console.log('error: '+data);
targetPane.setContent(data);
},
timeout: 3500,
form: frm
};
dojo.xhrPost(kw);
The 'frm' that above code is referencing gets created as pass-thru HTML with Computed Text on a Domino form:
var frm = document.forms['<Computed Text>']
and value for the text is:
"_" + Form
Posted by L. Laanti At 10:01:13 PM On 12/16/2007 | - Website - |
Thanks for sharing.
Posted by Lance At 03:58:16 AM On 12/17/2007 | - Website - |
Posted by Bob At 09:33:19 PM On 11/29/2007 | - Website - |
xhrPost will take the form name as its argument and then post all the fields it finds in that form, thus ignoring the query result just performed.
If, on the other hand, you are saying use dojo.query to get the nodes, perform your own node destruction, and then do xhrPost, yes, I assume that would work.
However, the problem should be fixed in the dojo source regardless. There's no value in submitting name/value pairs in a post to the backend if you don't have a name
Posted by Lance At 09:35:21 PM On 12/12/2007 | - Website - |
Posted by Alex Russell At 09:37:54 AM On 12/14/2007 | - Website - |
But I agree with David in that I can't really see a use-case where a submission of data without a name pair provides any value. For example, what would you do with this data stream resulting from a post:
firstName=Lance&lastName=Spellman&=888-111-1111&=Phoenix&State=AZ
You and I know by looking at it that the 888-111-1111 is a phone number, but the web server won't. And even if it could distinguish that, is it the office, home, or cell number? So the data has no value, and the potential for causing error on the server.
Also, since the data that will be submitted this way is NOT the core form data anyway, but simply the dojo mechanics for building widgets on the screen, it's unnecessary data.
For all those reasons, I would make the filter universal in the Dojo source. We'd submitted a bug in Tracker with the fix, but I can't locate it now.
Posted by Lance At 03:59:01 PM On 12/14/2007 | - Website - |
"it won't work because the dojo.query is only going to return a set of filtered nodes. xhrPost will take the form name as its argument"
My point was that xhrPost also accepts the form itself as parameter. Thus in my example above, when i write:
var kw = {
(...other stuff...)
form: frm
};
this frm is the DOM node that was modified with dojo.query and thus has the 'nameless' values removed.
So, I do not pass the form name to xhrPost. I pass the modified form itself. I included the rest of the code so that you could see where the frm was coming from.
Hope I was more clear this time.
This code actually works in my application (I am using dojo 1.0.0 from AOL CDN). I understand that change to source is not big, however I would not like to maintain a locally patched version.
Generally I agree with you that nameless values should not be sent to server. Maybe this will be fixed in 1.0.2.
Posted by L. Laanti At 01:39:17 AM On 12/17/2007 | - Website - |
The issue we're dealing with here is that once the form is rendered, along with all the little dojo widget bits and insertions, the input fields that are now inside that form don't all have 'name' attributes. When you use xhrPost, you are giving it the form element and it will scrape all the input tags inside that form to submit to the server.
Where it breaks is when those input fields don't have a name (what dojo does with some of it's helper input fields).
We don't really need to make a big deal of this, I'm sure it will be fixed in a maintenance release, and if you're in a hurry, it's 5 characters on one line of code in the dojo source to fix it.
Posted by Lance At 11:38:59 PM On 12/16/2007 | - Website - |
Posted by David Bokes At 02:41:43 AM On 12/12/2007 | - Website - |