By: Hazem Saleh










What is Dojo?
Dojo Architecture
dojo.js
Getting Started with Dojo
AMD
DOM functions
Event model
Ajax
References




Dojo is rich Java Web component framework
that can be used for building interactive Web
2.0 applications.
Dojo is an open source work.


Architecture:








Dojo base: The framework kernal (dojo.js) around 60 kb. It
contains the Ajax, Classes System (dojo.declare), dojo.query,
AMD ...etc.
Dojo core: Utilities over the dojo base. It contains i18n,
animation, integration with data sources (data stores), ...etc.
Dijit: Dojo Widgets.
Dojox: Dojo extension components (Includes Dojo mobile).
Util: Some Dojo utilities that have no access from web pages
(ShrinkSafe, DOH, ...etc)















Module Loader
Lang Utils (Classes System) & Array Extras
Cookie functions
Query, Node & Style Utils
I/O (Ajax)
JSON serialization
Fast CSS Style manipulation
Events
Color functions
Browser detection
URL functions
Animation Utilities






Include the CSS styles that your Dojo
application needs.
Include the dojo.js file as follows:
<script
src="http://ajax.googleapis.com/ajax/libs/doj
o/1.8.1/dojo/dojo.js" data-dojo-config="async:
true"></script>
Include the required modules.






Since Dojo 1.7, Dojo is complaint with the AMD
(Asynchronous Module Definition) standard.
Most of the Dojo modules are using AMD since
Dojo 1.7.
The benefits of AMD:
Asynchronous.
 Faster.
 Standard.




Dojo AMD modules can work with other
JavaScript libraries which supports AMD
(theoretically).
Dojo < 1.7 (synchronous):
dojo.require("dojo.cookie");
dojo.require("my.widget");
dojo.addOnLoad(function(){
alert("DOM is ready");
})


Dojo >= 1.7 (AMD asynchronous):
require(["dojo/cookie", "my/widget",
"dojo/domReady!"], function(cookie, myWidget){
alert("DOM is ready");
})

Dojo < 1.7 (Class Declaration):
dojo.provide("my.widget");
dojo.require("dijit._Widget");
dojo.declare("my.widget", dijit._Widget, {
// ...
});
 Dojo >= 1.7 (Class Declaration):
define(["dojo/_base/declare", "dijit/_Widget"],
function(declare, _Widget){
return declare(“my.widget”, [_Widget], {
// ...
});
});




AMD brings “convenient” modularity to Dojo.
Let’s see how to:





Create AMD module class.
Create AMD module object.

Let’s create the following:



Doubler class that has one method calculate (divID,
number).
Factorial object that has one method calculate (divID,
number).


Doubler class (Doubler.js under “custom” folder):

define([
"dojo/dom", "dojo/_base/declare"
], function(dom, declare){
return declare("Doubler", null, {
calculate: function(divID, number){
var node = dom.byId(divID);
node.innerHTML = "Double value (" + number + "):
" + (number * 2);
}
});
});
factorial object (Factorial.js under “custom” folder):



define([
"dojo/dom"
], function(dom){
return {
calculate: function(divID, number){
var node = dom.byId(divID);
var factorial = 1;
for (i = 1; i <= number; ++i) {
factorial *= i;
}

node.innerHTML = "Factorial value (" + number + "): " + factorial;
}
};
});


In order to use the “custom” module in the page,
you need to change Dojo config before Dojo script
include as follows:

<script>
var dojoConfig = {
async: true,
packages: [{
name: "custom",
location: location.href.replace(//[^/]*$/, '') +
"/custom"
}]
};
</script>
Use the module objects and classes peacefully:
require([..., "custom/Factorial",
"custom/Doubler", ...],
function(..., factorial, Doubler, ...) {
// ...
factorial.calculate("result1", 6);
new Doubler().calculate("result2", 6);
// ...
});



There are useful packages which are facilitating
DOM processing:
DOM retrieval:
require(["dojo/dom", "dojo/domReady!"],
function(dom) {


//Get DOM element by Id.
var one = dom.byId("one");
});
DOM Construction:
require(["dojo/dom", "dojo/dom-construct",
"dojo/domReady!"],
function(dom, domConstruct) {
var list = dom.byId("list");

domConstruct.create("li", {
innerHTML: "Seven",
className: "seven",
style: {
fontWeight: "bold"
}
}, list);

});


DOM destruction:




domConstruct.destroy(item) destroys
the item with all of its children.
domConstruct.empty(“someElement”)
destroys the children of the element
without destroying the element itself.
Simple Action:
require(["dojo/on", "dojo/dom",
"dojo/domReady!"],
function(on, dom) {
var myButton = dom.byId("myButton");


on (myButton, "click", function(evt){
alert("Iam clicked");
});
});


Publish/Subscribe model:

require(["dojo/on", "dojo/topic", "dojo/dom", "dojo/domReady!"],
function(on, topic, dom) {
var alertButton = dom.byId("alertButton");
on(alertButton, "click", function() {
// When this button is clicked,
// publish to the "alertUser" topic
topic.publish("alertUser", "I am alerting you.");
});
// Register the alerting routine with the "alertUser" topic.
topic.subscribe("alertUser", function(text){
alert(text);
});
});


“dojo/_base/xhr” module wraps the complexity of Ajax request
creation and response retrieval. Sample Ajax GET request:

require(["dojo/_base/xhr", "dojo/dom", "dojo/domReady!"],
function(xhr, dom) {
// Using xhr.get, as very little information is being sent
xhr.get({
// The URL of the request
url: "get-content.php",
// The success callback with result from server
load: function(newContent) {
dom.byId("contentNode").innerHTML = newContent;
},
// The error handler
error: function() {
// Do nothing -- keep old content there
}
});
});


Sample Ajax POST request:

var messageNode = dom.byId("messageNode");
// Using xhr.post, as the amount of data sent could be large
xhr.post({
url: "submission.php",
form: dom.byId("contactForm"),
load: function(response) {
messageNode.innerHTML = "Thank you for contacting us!";
},
error: function() {
messageNode.innerHTML = "Your message could not be sent, please try
again."
}
});
If you work with Dojo >= 1.8, use “dojo/request” module instead.



require(["dojo/dom", "dojo/on", "dojo/request", "dojo/domReady!"],
function(dom, on, request){
var resultDiv = dom.byId("resultDiv");
request.get("/someServlet").then(
function(response){
// Display the text file content
resultDiv.innerHTML = "<pre>"+response+"</pre>";
},
function(error){
// Display the error returned
resultDiv.innerHTML = "<div class="error">"+error+"<div>";
}
);
}
);


Dojo toolkit documentation:
http://dojotoolkit.org/documentation/




Twitter: http://www.twitter.com/hazems
Blog: http://www.technicaladvices.com
Email: hazems@apache.org

Dojo >= 1.7 Kickstart

  • 1.
  • 2.
             What is Dojo? DojoArchitecture dojo.js Getting Started with Dojo AMD DOM functions Event model Ajax References
  • 3.
      Dojo is richJava Web component framework that can be used for building interactive Web 2.0 applications. Dojo is an open source work.
  • 4.
     Architecture:      Dojo base: Theframework kernal (dojo.js) around 60 kb. It contains the Ajax, Classes System (dojo.declare), dojo.query, AMD ...etc. Dojo core: Utilities over the dojo base. It contains i18n, animation, integration with data sources (data stores), ...etc. Dijit: Dojo Widgets. Dojox: Dojo extension components (Includes Dojo mobile). Util: Some Dojo utilities that have no access from web pages (ShrinkSafe, DOH, ...etc)
  • 5.
                Module Loader Lang Utils(Classes System) & Array Extras Cookie functions Query, Node & Style Utils I/O (Ajax) JSON serialization Fast CSS Style manipulation Events Color functions Browser detection URL functions Animation Utilities
  • 6.
       Include the CSSstyles that your Dojo application needs. Include the dojo.js file as follows: <script src="http://ajax.googleapis.com/ajax/libs/doj o/1.8.1/dojo/dojo.js" data-dojo-config="async: true"></script> Include the required modules.
  • 7.
       Since Dojo 1.7,Dojo is complaint with the AMD (Asynchronous Module Definition) standard. Most of the Dojo modules are using AMD since Dojo 1.7. The benefits of AMD: Asynchronous.  Faster.  Standard.   Dojo AMD modules can work with other JavaScript libraries which supports AMD (theoretically).
  • 8.
    Dojo < 1.7(synchronous): dojo.require("dojo.cookie"); dojo.require("my.widget"); dojo.addOnLoad(function(){ alert("DOM is ready"); })  Dojo >= 1.7 (AMD asynchronous): require(["dojo/cookie", "my/widget", "dojo/domReady!"], function(cookie, myWidget){ alert("DOM is ready"); }) 
  • 9.
    Dojo < 1.7(Class Declaration): dojo.provide("my.widget"); dojo.require("dijit._Widget"); dojo.declare("my.widget", dijit._Widget, { // ... });  Dojo >= 1.7 (Class Declaration): define(["dojo/_base/declare", "dijit/_Widget"], function(declare, _Widget){ return declare(“my.widget”, [_Widget], { // ... }); }); 
  • 10.
      AMD brings “convenient”modularity to Dojo. Let’s see how to:    Create AMD module class. Create AMD module object. Let’s create the following:   Doubler class that has one method calculate (divID, number). Factorial object that has one method calculate (divID, number).
  • 11.
     Doubler class (Doubler.jsunder “custom” folder): define([ "dojo/dom", "dojo/_base/declare" ], function(dom, declare){ return declare("Doubler", null, { calculate: function(divID, number){ var node = dom.byId(divID); node.innerHTML = "Double value (" + number + "): " + (number * 2); } }); });
  • 12.
    factorial object (Factorial.jsunder “custom” folder):  define([ "dojo/dom" ], function(dom){ return { calculate: function(divID, number){ var node = dom.byId(divID); var factorial = 1; for (i = 1; i <= number; ++i) { factorial *= i; } node.innerHTML = "Factorial value (" + number + "): " + factorial; } }; });
  • 13.
     In order touse the “custom” module in the page, you need to change Dojo config before Dojo script include as follows: <script> var dojoConfig = { async: true, packages: [{ name: "custom", location: location.href.replace(//[^/]*$/, '') + "/custom" }] }; </script>
  • 14.
    Use the moduleobjects and classes peacefully: require([..., "custom/Factorial", "custom/Doubler", ...], function(..., factorial, Doubler, ...) { // ... factorial.calculate("result1", 6); new Doubler().calculate("result2", 6); // ... }); 
  • 16.
     There are usefulpackages which are facilitating DOM processing: DOM retrieval: require(["dojo/dom", "dojo/domReady!"], function(dom) {  //Get DOM element by Id. var one = dom.byId("one"); });
  • 17.
    DOM Construction: require(["dojo/dom", "dojo/dom-construct", "dojo/domReady!"], function(dom,domConstruct) { var list = dom.byId("list"); domConstruct.create("li", { innerHTML: "Seven", className: "seven", style: { fontWeight: "bold" } }, list); });
  • 18.
     DOM destruction:   domConstruct.destroy(item) destroys theitem with all of its children. domConstruct.empty(“someElement”) destroys the children of the element without destroying the element itself.
  • 19.
    Simple Action: require(["dojo/on", "dojo/dom", "dojo/domReady!"], function(on,dom) { var myButton = dom.byId("myButton");  on (myButton, "click", function(evt){ alert("Iam clicked"); }); });
  • 20.
     Publish/Subscribe model: require(["dojo/on", "dojo/topic","dojo/dom", "dojo/domReady!"], function(on, topic, dom) { var alertButton = dom.byId("alertButton"); on(alertButton, "click", function() { // When this button is clicked, // publish to the "alertUser" topic topic.publish("alertUser", "I am alerting you."); }); // Register the alerting routine with the "alertUser" topic. topic.subscribe("alertUser", function(text){ alert(text); }); });
  • 21.
     “dojo/_base/xhr” module wrapsthe complexity of Ajax request creation and response retrieval. Sample Ajax GET request: require(["dojo/_base/xhr", "dojo/dom", "dojo/domReady!"], function(xhr, dom) { // Using xhr.get, as very little information is being sent xhr.get({ // The URL of the request url: "get-content.php", // The success callback with result from server load: function(newContent) { dom.byId("contentNode").innerHTML = newContent; }, // The error handler error: function() { // Do nothing -- keep old content there } }); });
  • 22.
     Sample Ajax POSTrequest: var messageNode = dom.byId("messageNode"); // Using xhr.post, as the amount of data sent could be large xhr.post({ url: "submission.php", form: dom.byId("contactForm"), load: function(response) { messageNode.innerHTML = "Thank you for contacting us!"; }, error: function() { messageNode.innerHTML = "Your message could not be sent, please try again." } });
  • 23.
    If you workwith Dojo >= 1.8, use “dojo/request” module instead.  require(["dojo/dom", "dojo/on", "dojo/request", "dojo/domReady!"], function(dom, on, request){ var resultDiv = dom.byId("resultDiv"); request.get("/someServlet").then( function(response){ // Display the text file content resultDiv.innerHTML = "<pre>"+response+"</pre>"; }, function(error){ // Display the error returned resultDiv.innerHTML = "<div class="error">"+error+"<div>"; } ); } );
  • 24.
  • 25.