Thursday, February 28, 2008

Dojo xhr to update a div

Using ajax to update a portlet quickly becomes a requirement when you get a bunch of portlets on a page and reloading everything is slow. So in setting out to use dojo to do this, I figured it required nothing more than setting the innerHTML of my div with the new content. It's not that simple, however, if the panel contains dojo's "dijit" widgets (in this case, I had a dijit.layout.TabContainer returned with the ajax content). BTW, dojo folks, the TabContainer worked flawlessly right out of the box and was clean and simple--nice job. In comparing the before/after, it was apparent that when the div content was rendered when the entire page loaded, dojo/dijit was wiring up the tab elements with all the required events and attributes. However, when the ajax content was set as innerHTML, this wasn't happening. It was a bit tough to figure out mostly because I wasn't sure what to google on to find the solution. I tried a few things, including making the div for the content a dijit.layout.ContentPane--but that's just part of what's needed. Here's what the content pane div looks like:
<div id="ajaxReportBody" dojoType="dijit.layout.ContentPane">
<c:import url="reportBody.jsp" />
</div>

The other piece is to make sure you use setContent() in your xhr load function on the dijit widget (in this case, the content pane div), instead of innerHMTL:
dojo.xhrPost( { 
...
load: function(response, ioArgs) {
...
dijit.byId("ajaxReportBody").setContent(response); // KEY!
return response;
},
...

When you use setContent(), dijit will redo the plumbing in the new content for you. Also note that you must use digit.byId(), not dojo.byId().

Some references indicated that you need an executeScripts="true" on the content pane div. However, this is no longer true AFAICT (I'm using dojo 1.0.2).

BTW, best reference I found on the subject was here.