Saturday, April 24, 2010

Dojo widgets and their domNode

Today, I understood better with dojo widget which is so called dijit system. I realized more about what a dojo widget deeply is and how they are formed. Here I want to share my experience with every reader.

First, I want to talk about the difference between dijit.byId() and dojo.byId() which will be heavily used by any dojo user. To summarize, dijit.byId() returns a dijit (dojo widget) and dojo.byId() returns a dom node. A dojo widget maybe formed by many dom nodes, and within dojo toolkit, a widget is also a javascript object. To better explain this, lets look at a dijit.form.TextBox created below:



< div id="iBox" dojoType="dijit.form.TextBox">< /div>


What will be the output be if we simply just do dijit.byId("iBox")? It will output "[Widget dijit.form.TextBox, iBox]. it means what dijit.byId("iBox") returns is a widget object. It is very clear and simple to someone who has already had experiences with dojo; as you see there, because we created a widget in the markup, we are supposed to get a widget returned from dijit.byId().

what about dojo.byId("iBox")? what will it return? It returns a dom node object with value [Object HTMLInputElement]! Wait a second here! As what I described above -- dojo.byId() returns the dom node, should it return [Object HTMLDivElement] then? No, absolutely not. The reason is that when dojo parse the widget, it will replace the markup you created with something else pre-defined in the templates. For the dijit.form.TextBox widget, please go to your dojo directory, open folder "dijit", then open folder "form" under "dijit", then open the "TextBox.html" file within the "templates" folder under "form" folder. What you see in the html template file is how the TextBox widget is rendered. As you would expect, it is rendered by "input" tag. Thats just why dojo.byId("iBox") returns an "input" element. The same output will be obtained if you do dijit.byId("iBox").domNode. However, it is not always true!!!!

if dojo.byId() is used on a dijit, it will output the most effective tag wrapped to this dijit; whereas dijit.byId().domNode will returned the outermost tag wrapped to the dijit. For example:

< div id="iButton" dojotype="dijit.form.Button">< /div>

This is a dijit.form.Button widget, again looking down to its template, you will see a "button" tag is wrapped by 3 "span" tags outside of it. In this case, the outermost "span" tag is the outermost html tag wrapped to this widget, whereas the "button" tag is the most effective tag of this widget. As you would expect, dojo.byId("iButton") will output "[Object HTMLButtonElement]" whereas dijit.byId("iButton").domNode will output "[Object HTMLSpanElement]".

Here comes another question, where did the "id" attribute get assigned to? The answer is the most effective dom node. It turns out that dojo.byId("iButton").id will actually return the id "iButton" (even if it is considered a bad way in practice), whereas dijit.byId("iButton").domNode.id will return nothing -- "undefined" (it is an even worse example in practice).