I have a form with a table that has two input boxes, a select box, and a few checkboxes. All form fields use dojoType=”dijit.form.{theFieldType}”.
When the user clicks the add button a new table with the same fields is loaded from a jsp file. This is my ajax function:
<script language="javascript">
dojo.addOnLoad(passNumber);
function passNumber() {
var count = 0;
dojo.query('#add').onclick(function() {
var dNode = dojo.byId('more');
count++;
dojo.xhrGet({url: 'add.html',
handleAs: "text",
preventCache: true,
content:{fieldId:count} ,
load: function(data) {
dNode.innerHTML += data;
dojo.parser.parse(dNode);
},
error: function(error) {
dNode.innerHTML += "AJAX error: " + error;
}
});
});
}
</script>
When clicking the add button everything works like it should.
The problem arises when you click the add button more than once. On multiple clicks the fields in the table get added to the form correctly but all the dojoType fields are now read-only (except the newest added table).
I searched for a few hours this morning and could not find the correct fix for this. I saw some people posted about destroying the objects while other talked about only parsing the newest fields. I tried several techniques and could not get it to work.
I have a simple work around that might help someone in the same position.
<script language="javascript">
dojo.addOnLoad(passNumber);
function passNumber() {
var count = 0;
dojo.query('#add').onclick(function() {
var dNode = dojo.byId('more'+count);
count++;
dojo.xhrGet({url: 'add.html',
handleAs: "text",
preventCache: true,
content:{fieldId:count} ,
load: function(data) {
dNode.innerHTML = data;
dojo.parser.parse(dNode);
},
error: function(error) {
dNode.innerHTML += "AJAX error: " + error;
}
});
});
}
</script>
The main difference is the += in the dNode.innerHTML is now an = only. Also I only parse the newest div element. On my jsp I added an empty div container called ‘more’ + the number passed.
I am new to dojo so there might be an easy explanation or fix for my original problem. But I wanted to share my fix for anyone running into the same issue.
Thanks
You have at least one, and possibly two, problems.
Firstly, you should use
dojo.placeto place the HTML fragment in the page, notinnerHTML.Secondly (and you may not be doing this) you shouldn’t ever run the parser over a part of the DOM where the parser has already been run. If you do you’ll end up with the error ‘Tried to register a widget with if ‘foo’ but that id is already registered’.
Basically, just like IDs have to be unique for DOM nodes, they have to be unique for widgets too.
You have a couple of options:
Don’t return a document fragment/HTML text from your JSP. Instead, use JSON or similar and construct the new form elements programmatically in the
load()callback.Do what you’re doing (but make sure you’ve got unique IDs) but rather than using
innerHTMLusedojo.place(). Then keep track of the new table node you’re creating and only parse that.For example:
I’ve added an example of this working at http://telliott.net/dojoExamples/dojo-xhrBuildDomExample.html. The HTML returned by the AJAX call can be found at http://telliott.net/dojoExamples/_data/mockBackendForXhrBuildDomExample.php (it uses the PHP time() function, so don’t hit the button more than once a second!).
HTH,
Tom