Code difference between normal and dijit elements

You have seen how to add an onClick event to a dijit element in Chapter 4. I like to show how the code is rendered and why the normal onclick method fail to add a handler to a click event. See the screenshot below and compare the code of the button, highlighted in blue, for a dijit and normal element.

In the above screenshot, you can notice how the "id" given for the button has been rendered as the "widgetid" by dojo engine. So if you do a query search for id="dojoButton" is no more available in the DOM and hence will result in error.
That is the reason we should write using dijit.byId method to refer the dijit elements. Just shown below is the code from chapter 4, for your reference.

dojo.connect(dijit.byId("dojoButton"), "onClick", function(){
dojo.query("#content").text("Welcome "+dijit.byId("nameText").attr("value"));
});

Keep in mind, if you use same id value for more than one element, the engine will end up in error, without applying the required effect and functionality to the dijit elements.

Introduction to Dijit Widgets

It may me earlier to introduce dijit in this chapter. But it is not hard to push it as a last topic.
Dojo toolkit provide many widgets with many properties pre-programmed to reuse. So it is easy for the programmers to include this widget and override the properties as required. Dijit is built on top of dojo and hence require dojo core.

Let us understand it quickly with a code with  textbox and button example.

Normal approach:
<input type="text" id="nameText" value="Enter Name" /><br />
<input type="button" id="clickBtn" value="Click" />

Dijit approach:
<input id="nameText" dojoType="dijit.form.TextBox" value="Enter Name" > </input><br />
<button id="dojoButton" dojoType="dijit.form.Button">Click</button>


Once the dojoType="dijit.form.Button" is added as an attribute to the element, dojo will convert it to its dijit element. Dijit can use the styles automatically while you include the dojo's themes. You can see it on browser with the following code. You should note the lines marked in bold in the code below.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dijit Button Event</title>
<link  href="js/dijit/themes/claro/claro.css" rel="stylesheet"/>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dijit/themes/claro/claro.css">
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js" djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
//Remember to import the following modules
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");
dojo.require("dojo.NodeList-manipulate");//"text" method is defined inside this module.
dojo.ready(function(){
//note how I have binded the onClick function for the dijit button.
//if you try to access the button using dojo.byID or dojo.query methods
//it will fail. I will explain this in next chapter in detail.
dojo.connect(dijit.byId("dojoButton"), "onClick", function(){
dojo.query("#content").text("Welcome "+dijit.byId("nameText").attr("value"));
});
});
</script>
</head>
<body class="claro">
<label for="nameText">Enter Your Name: </label>
<input id="nameText" dojoType="dijit.form.TextBox"></input>
<br />
<button id="dojoButton" dojoType="dijit.form.Button">Show Content</button>
<div id="content"></div><!-- container to receive the value from the text box -->
</body>
</html>

The code above will get the value of the text box entered by the user and write it inside the div container on click of the button. This code add onClick event to the dijit button.
dojo.connect(dijit.byId("dojoButton"), "onClick", function(){
dojo.query("#content").text("Welcome "+dijit.byId("nameText").attr("value"));
});

Print only a div content

Here is an example, to print content of a particular div without opening it in a separate window. I have used few techniques with CSS style to define which content should be available to print and which should not. So you can find out in the code below that I have used @media print { } to define the styles for print media and @media screen { } to define the styles for screen media. 

I have used dojo's clone method to copy the content from the div inside the main block and append it to the printable div. Thus you can print content in a particular div. Also you can develop it further by adding different contents from different locations in a page, avoiding certain elements like button, to print.

Remember to import NodeList-manipulate module for clone() method to work. Also I have used behavior to define onclick properties of the Print buttons. So you need to import behavior modules of dojo.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Print Function</title>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js.uncompressed.js'></script>
<script type="text/javascript">
dojo.require("dojo.NodeList-manipulate");
dojo.require("dojo.behavior");
dojo.ready(function(){
//Use any of the method to initiate behaviour properties for print button
//Method: 1
/*var printInitiate = ({
".printBtn":{
onclick: function(evt){
dojo.query("#content").clone().appendTo(".printer");
window.print();
}
}  
});
dojo.behavior.add(printInitiate);*/
//Method: 2
dojo.behavior.add({
".printBtn":{
onclick: function(evt){
dojo.query("#content").clone().appendTo(".printer");
window.print();
}
}  
});
dojo.behavior.apply();
});
</script>
<style type="text/css">
@media print {
div.main {
display:none; /*Code makes the entire content of the main div unavailable to print */
}
div.printer {
display:block; /*Code makes the printer div available to print */
}
}
@media screen {
div.main {
display:block; /*Code makes the entire content of the main div available to screen */
}
.printer {
display:none; /*Code makes the printer div unavailable to screen */
}
}
</style>
</head>
<body>
<div class="main">
  <p>This content not required to print. The entire content is inside a main div. I have used a div declared as display: none, outside of the main div.</p>
  <p>I have used css style to make it available to the print media and not available to the screen media.</p>
  <p>On click of the print button on screen the contents within the div with id=content, will be cloned to the div outside of the main div making it available to the print media</p>
  <input type="button" value="Print" class="printBtn" />
  <p>############# Printable Content ##################</p>
  <div id="content">
    <p>First Line</p>
    <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit</p>
    <p>Second Line</p>
    <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit</p>
  </div>
  <p>############# Printable Content End ##################</p>
  <input type="button" value="Print" class="printBtn" />
  <div>The content is below and not required to Print.</div>
  <p> Remember to make the entire content within the main div unavailable to the print media.</p>
</div>
<div class="printer"></div>
</body>
</html>

Node Traverse / Access page elements based on its relationship

We have learnt, how to access an element in the page using its ID, Tag name and class in Lesson-2. In this chapter we will see how to access the DOM elements (nodes) based on its relationship with each other. This in technical terms we call it as traverse. So keep in mind to use this methods, it is required to include NodeList-traverse.

In dojo, hope you are aware how to include the module. It is simple,
dojo.require("dojo.NodeList-traverse");

Methods:

  1. parent - to get the parent node of a particular node
  2. parents - to get all the parents of a particular node
  3. children
  4. siblings
  5. next
  6. nextAll
  7. prev
  8. prevAll
  9. closest
  10. andSelf - usually the above all methods will get the nodes accordingly without including the particular node. By using this method, the pointed node will also get included in the list of nodes selected.

    The above methods, as the name indicates, brings up the list of nodes related to a particular node. But there are few more methods defined by NodeList-traverse, which on my view work as filter. They are
  11. first
  12. last
  13. even
  14. odd
Each methods are explained with examples in dojotoolkit in this page (http://dojotoolkit.org/reference-guide/dojo/NodeList-traverse.html#dojo-nodelist-traverse). So I feel it is not required to give examples for all again here. If you have any questions or if you need any help on this topic, please post in comments.

The key point to keep in mind to use this method is to add dojo.require("dojo.NodeList-traverse");  in your code.

Example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tech Prem - Dojo Lesson-2</title>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js" type="text/javascript"></script>
<script type="text/javascript">
dojo.ready(function()
{
dojo.require("dojo.NodeList-traverse");
dojo.require("dojo.NodeList-manipulate");

dojo.query("#parent1").onclick(function(){
dojo.query(".result").text("My Childrens are: "+dojo.query(".parent_1").children().attr("class"));

});
dojo.query("#child3").onclick(function(){
dojo.query(".result").text("My parent is: "+dojo.query(".child_3").parent().attr("class"));
});
dojo.query("#showall").onclick(function(){
dojo.query(".result").text("My parent are: "+dojo.query(".child_3").parents().attr("class"));
});
 
});
</script>
</head>
<body>
<div class="parent_1">
<div class="child_1">I am child_1</div>
<div class="child_2">I am child_2, I have another child <br/>
<div class="child_3">&nbsp;&nbsp;&nbsp;&nbsp;I am child_3, I am child of child_2</div>
</div>
</div>
<input type="button" id="parent1" value="Show list of parent - 1's children"/>
<input type="button" id="child3" value="Show child-3's parent"/>
<input type="button" id="showall" value="show child-3's all parent" />
<p>Results</p>
<div class="result"></div>
</body>
</html>

Code:


Document Object Model (DOM)


If you are new to DOM, you can get some knowledge at http://www.w3schools.com/htmldom/default.asp

Study on the following topics

Understand Parent, Children, Siblings and its hierarchical relationship.

Let me directly show few techniques to access the elements of the page using dojo.
The DOM nodes can be accessed by using its
  1. ID
  2. TagName
  3. Class
  4. Node Relationships

We will see each one of this with examples in the following topics.

Using ID:
To access an element using its ID, dojo provides two base methods
dojo.byId("just_the_id_of_element");
dojo.query("#followed_by_id_of_element");
If you know jquery, at this point of time, for easy understanding, consider dojo.query is similar to jQuery ie $("#followed_by_id_of_element");

Using TagName:
dojo.query("tagName");

Using Class:
dojo.query(".class_Name");

I will deal with node relationships in the next lesson. Let me show an example to access elements using ID, TagName and Class.

Code:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tech Prem - Dojo Lesson-2</title>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js" type="text/javascript"></script>
<script type="text/javascript">
dojo.ready(function()
{
  dojo.require("dojo.NodeList-manipulate");
  dojo.query("input").onclick(function(){
 dojo.query("p").text("The content changed after click of the button");
 dojo.style(dojo.byId("firstID"),"color","red");
 dojo.query(".firstClass").style("width","150px");
  });
});
</script>
<style type="text/css">
#firstID {color:#666;}
.firstClass {width:100px; height:50px; background-color:#9C6;}
</style>
</head>
<body>
<p>Initial Content in P tag</p>
<div id="firstID">My Color will Change to red</div><br />
<div class="firstClass">This box will grow...</div><br />
<input type="button" value="Access DOM" />
</body>
</html>


Code Explained:

dojo.query("p").text("The content changed after click of the button");
The "P" tag accessed using the tag name. To use text method, it is required to include NodeList-manipulate. So I have included it by using dojo.require.

dojo.style(dojo.byId("firstID"),"color","red");
The color of the text inside the div with ID="firstID" has been changed by accessing the div using byId method.


dojo.query(".firstClass").style("width","150px");
The width of the div has been set to 150px by accessing the div using its class attribute "firstClass".