Dojo migration 0.4 to 0.9, a summary
First things first, if your project allows you to migrate to 0.9 (you got the time to do it) - do it! It’s worth all the sweat and it might cost you some.
I have converted a mid-size project from dojo 0.4 to 0.9 and it took longer than I thought, but also because I had to collect all the info from multiple places, so I will try to share what I discovered or collected and hoepfully make it easier to migrate. Good luck!
If you come across more changes that match somewhere in the list just add them to the comments, I will try to incorporate them.
Namespaces
Some functions have changed their namespaces. Most common functions have moved to dojo.* namespace to simply be quickly reachable. Simply do a console.dir(dojo) on the FireBug console, which lists all the functions that are located in the dojo.* namespace.
I found those changes:
dojo.lang.* => dojo.* dojo.lang.find => dojo.lang.indexOf dojo.lang.filter => dojo.filter dojo.html.* => dojo.* dojo.html.hasClass => dojo.hasClass dojo.html.addClass => dojo.addClass dojo.html.removeClass => dojo.removeClass dojo.html.toggleClass => dojo.toggleClass dojo.widget.byId => dijit.byId dijit.byNode is new, the speeks for itself imho
Some functions disappeared
dojo.lang.isUndefined() disappeared, I didnt find the reasoning anywhere yet. If you have no deeply nested objects you try to check, a function isUndefined() will work well I created one for my project. If you don’t like that I guess you have to replace all calls with typeof varName == "undefined".
dojo.lang.isNumber() disappeared too. My solution:
function isNumeric(v) {return dojo.number.format(v)!==null};.
dojo.html.getPadding() was removed and seems to have become dojo.style(el, "paddingLeft"), dojo.style(el, "paddingRight"), etc. and that looks reasonable, it only gets the data you really need not all the paddings though you would have needed only one.
dojo.html.getScroll() is gone, the hack I use is dojo._docScroll() which does return the data as I need them, but it looks very private :-(.
dojo.dom.removeNode(el) was removed since the same can easily be achieved el.parentNode.removeChild(el), though removeNode() was pretty convinient, but not really necessary. Another intelligent move.
dojo.string.escape() is gone too. I just copied the old 0.4 function (dojo.string.escapeXml() see here for the source) into my local project namespace, I didnt find a replacement in dojo0.9 yet :-(. Probably also a simple thing like the removeNode thing, but I don’t know yet.
Important function changes
dojo.html.toCoordinateObject() was renamed to dojo.coords() which is a good move, since it was way too long. It now returns an object with the keys: w,h,t,l (width, height, top, left). Much more efficient.
this._inherited() is not a function anymore, but I guess I was one of the few who used it directly though I shouldn’t. Now call this.inherited("funcName", arguments).
I think that only due to a bug or missing implementation I used to use _inherited() now it seems to be fixed and as it is supposed to be.
But: inherited() can only be called for the same function as the callee … strange, so we have to use className.functionName.apply(this, arguments) and that is one thing that really sucks, since you hard code the className in the class … I hope that will change.
dojo.fx.html.wipeOut(el, 1000, null, onEnd) changes to this dojo.fx.wipeOut({node:el, duration:1000, easing:null, onEnd:onEnd}).
For all the properties see the dojo._Animation object’s properties are all you can pass to the wipe-method.
Widget stuff
djConfig.searchIds forget about them!
Alex Russel told me in IRC
[12:35] cain: what is the replacement for “djConfig.searchIds” ?
[12:35] slightlyoff: cain: there isn’t one
[12:35] cain: how do i add ids to be rendered as widgets?
[12:35] slightlyoff: cain: there’s only a larger toggle (parseOnLoad)
[12:35] slightlyoff: cain: or you can run the parser yourself on a smaller subtree
[12:35] slightlyoff: cain: but in 0.9, the parser is much much much faster
So all you need to do is put djConfig.parseOnLoad=true at the beginning of your page and all widgets will be found. But be careful you have to manually dojo.require all the widget classes, iirc it was done automatically in 0.4.
The porting guide says:
you must require the Dojo parser along with any widgets referenced, and enable a page scan using the “parseOnLoad” setting
that sucks, for the parser could easily find out which class/file to load, now i have to handish require things.
In place of dojo.widget.createWidget(), simply use the Javascript “new” constructor. I.e. var dialog = new dijit.Dialog(params).
Replace all by
. The use of namespaces for creating widgets is straightforward now, in 0.4 it was strange. Great.
When building your own widgets you surely used the following dojo.uri.moduleUri that has become dojo.moduleUrl.
dijit.form.Form.getValues() is currently ignoring all fields inside the form if they are not widgets :-(, in 0.4 it didn’t.
dojo.widget.ComboBox is now dijit.form.ComboBox remotely loaded data are now realized via the dojo.data API. Before you simply specified a dataUrl attribute now that requires a dojo.data-store. And if you have a huge set of data on the server that you actually want to use the ComboBox to filter on, you will need this patch!
Replace dojo.widget.Form not with dijit.form.Form, but don’t make it a widget and use dojo.formToObject() instead, its much more efficient and explicit.
dojo.widget.Editor2 has become dijit.Editor, the toolbar config is much easier now, it used to be in an external file, now it’s as simple as that:
There is a problem loading it into a hidden layer, see this ticket there is work on the way see this comment.
Other stuff
In 0.4 it was not such a trivial task to make dojo render widgets that were in a chunk of HTML, that was loaded via AJAX. Now parsing a HTML chunk and render widgets in there simply is a call to dojo.parser.parse(node).
For most uses dojo.io.bind() has become dojo.xhrPost()/dojo.xhrGet() and the return data have been extended quite a bit.
If you have a form, that is a dijit.form.Form widget and you have some extra attributes, that the widget doesnt support by default in there, as i.e. “action” they will be kicked out, I used the following patch http://trac.dojotoolkit.org/ticket/4392 to have them added again. But there seems to be changes going on in this area, there is some attributeMap added, but I am not sure if this is the way and if that stays.
In the bootstrap.js i found the following comment:
Refer to ‘dojo.global’ rather than referring to window to ensure your code runs correctly in contexts other than web browsers (eg: Rhino on a server).
That means (and is also practiced in dojo) dont access “window” directly anymore but via “dojo.global” to me that sounds like it might make a lot of sense to simplify testing outside the browser, but I need to see that in action somehow.
Dojo is going the very efficient and elegant way of using one function as setter and getter in many places, the setter looks like this:
dojo.cookie("name", value, {param:1, ... });
or the getter, which is the same function(!) is simple as that
var value = dojo.cookie("name");
This makes the API so much simpler, the code cleaner and simply simpler. Very handy.
That’s just a plain list of what I have found and remembered to write down. hth
Ann Ames said,
October 31, 2007 at 10:11 pm
Thanks for the info about dojo.parser.parse(node) - you saved me!
Wolfram said,
November 1, 2007 at 10:23 am
You are welcome, that’s what I hoped this article would do - help!
david said,
October 9, 2008 at 10:27 am
Great article, It helped me smoothly migrate an old dojo 0.4 app!