Dojo javascript toolkit


Published on

A beginner guide to Dojo Javascript Framework

Published in: Technology, Education
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Dojo javascript toolkit

  1. 1. Dojo Toolkit Predhin Tom Sapru
  2. 2. Do you know? HTML JavaScript Ajax DOM Web Browsers HTML Events
  3. 3. Hmm Should I use Dojo? • Dojo saves time and scales with the web development process, using web standards as its platform. It’s the toolkit experienced developers turn to for building high quality desktop and mobile web applications • Dojo Toolkit is an open source modular JavaScript library designed to ease the rapid development of cross-platform, JavaScript/Ajax-based applications and web sites Dojo Supports
  4. 4. Browser gaps • • • • • Ajax CSS(class manipulations/reset, CSSOM) DOM(Events, Node lookups, placements, attributes) Language Awkwardness (type detection, dates) Forward looking API(animation, vector graphics, querying, widgets, charts etc.)
  5. 5. What is Dojo? – Dojo is JavaScript framework released as open source software. This JavaScript toolkit provides many components to develop rich internet applications. – You can use Dojo toolkit to develop dynamic web applications. Dojo toolkit will put life in your web application and turn it into highly interactive application. You can turn your web application into desktop like web application. – Dojo offers many widgets, utilities and ajax libraries to develop your application. – Dojo is released under BSD or AFL license – Dojo is free and can be used to develop free or commercial application.
  6. 6. What are the features of Dojo? Powerful APIs Rich UI Widgets Open Source • Dojo's powerful, lightweight core makes common tasks quicker and easier • Don’t spend hours reinventing the wheel, use Dojo’s widget system Dijit for commonly used form widgets like calendars, input validation and more.. • Use and modify Dojo in commercial and Open Source software with confidence Desktop, Mobile • Provides support for both desktop and mobile applications Grids and Charts • Create enterprise grade apps with grids and charts that work across browsers and can handle any data thrown at it Asynchronous Loading • Only load the capabilities you need, all asynchronously and FAST
  7. 7. What is the history of Dojo? • Alex Russell, David Schontzler, and Dylan Schieman started work on the Dojo framework by in 2004 while working for Informatica. Later many other developers started contributing to Dojo. In 2005, the Dojo foundation was formed to house the code and manage intellectual-property rights. So far, eleven major releases have been issued, and the framework has been downloaded more than 1 million times. Companies such as IBM, AOL, Sun, SitePen, Blogline, Google, Nextweb, and others contribute to the Dojo framework.
  8. 8. Still Why Choose Dojo? • Breadth and Depth: Dojo is the “full stack”. Instead of cobbling together components from several different sources, Dojo allows each component to build on a trusted set of highquality building blocks by providing integrated infrastructure and a wide variety of optional modules. • Quality: Infrastructure for internationalization and accessibility is woven through the entire fabric of Dojo. • Performance: Dojo is used on high-profile, high-traffic sites every day and Dojo’s build tools are a key reason why. Dojo’s package system makes it easy to manage large-scale UI development projects and the build system layers on top to make your applications scream; all without code changes.
  9. 9. Why Choose Dojo? • Community: Dojo is an open community. As a result many individuals and companies have been able to come together on a level playing field to build tools that benefit everyone. • Asynchronous Module Definition (AMD): API for defining reusable modules that can be used across different frameworks. AMD was developed to provide a way to define modules such that they could be loaded asynchronously using the native browser script element-based mechanism.
  10. 10. What is the architecture of Dojo?
  11. 11. What are the different layers of Dojo? • As a framework, Dojo has three main components: • The Dojo core provides core functionality such as ability to make remote method calls, manipulate DOM node, and manipulate Cascading Style Sheets (CSS). The Dojo core also supports animation features and drag-and-drop functionality. • Dijit is Dojo's widget library, built on top of the Dojo core. Dijit provides template-based, accessible widgets, not only for simple form control but also advanced widgets such as calendar control, menus, toolbars, progress bars, charts, and graphs. • DojoX is a container for developing extensions to the Dojo toolkit. It acts as an incubator for new ideas and a testbed for experimental additions to the main toolkit, as well as a repository for more stable and mature extensions.
  12. 12. How can I get Dojo? Step 1: Got to the Dojo Toolkit download link : Step 2: Download dojo 1.9 JS files Step 3: Extract the dojo1.9 ZIP file Step 4 : Dojo, Dijit, Dojox folders will be available
  13. 13. How can I setup Dojo? • Setting up a development environment for a JavaScript framework like Dojo is a little different from doing so for Java SE or EE frameworks/ ASP.NET/PHP applications. • The Dojo toolkit depends on set of JavaScript, CSS, and HTML files to be available in a predefined directory structure at runtime. You can install Dojo in one of two ways: * Use Dojo from a content-delivery network (CDN) * Install the latest development build on your server
  14. 14. How to load Dojo? <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Tutorial: Hello Dojo!</title> <!-- load Dojo --> <script src="../dojo/dojo.js" data-dojo-config="async: true"></script> </head> <body> <h1 id="greeting">Hello</h1> </body> </html>
  15. 15. What is dojoConfig ? • dojoConfig object (known as djConfig prior to Dojo 1.6) is the primary mechanism for configuring Dojo in a web page or application. It is referenced by the module loader, as well as Dojo components with global options. • • <!-- set Dojo configuration, load Dojo --> dojoConfig= { has: { "dojo-firebug": true }, parseOnLoad: false, foo: "bar", async: true };
  16. 16. What are dojoConfig has() Configuration ? • We can specify features for the has() feature set in dojoConfig • • • This feature set is now used for determining certain supported capabilities in Dojo. Example we can disable or enable debug messages <script> dojoConfig = { has: { "dojo-debug-messages": true } }; </script> • dojo-firebug : To enable debugging assistance with Firebug Lite for older versions of Internet Explorer dojo-debug-messages : To log debug messages debugContainerId: specify a particular element to contain the console UI. popup: use a popup window rather than rendering the console into the current window • • •
  17. 17. What is dojoConfig Loader Configuration? • New loader added a few new configuration options that are crucial to defining packages, aliases, and more. • baseUrl: The base URL prepended to a module identifier when converting it to a path or URL. baseUrl: "/js” • packages: An array of objects which provide the package name and location: packages: [{ name: "myapp", location: "/js/myapp" }] • aliases: Allows you to alias modules by another name aliases: [ // [alias name, true name] ["cookie", "dojo/cookie"] ]
  18. 18. What are common dojoConfig properties? • async: Defines if Dojo core should be loaded asynchronously. async: true • deps: An array of resource paths which should load immediately once Dojo has loaded deps: *"dojo/parser“+ • parseOnLoad: If true, parses the page with dojo/parser when the DOM and all initial dependencies (including those in the dojoConfig.deps array) have loaded. parseOnLoad: true • callback: The callback to execute once deps have been retrieved: callback: function(parser) { } • waitSeconds: Amount of time to wait before signaling load timeout for a module; defaults to 0 (wait forever): waitSeconds: 5 • cacheBust: If true, appends the time as a querystring to each module URL to avoid module caching: cacheBust: true
  19. 19. Give an example of dojoConfig sample code? <script> dojoConfig = { has: { "dojo-firebug": true, "dojo-debug-messages": true }, // Don't attempt to parse the page for widgets parseOnLoad: false, packages: [ { name: "demo", location: "/documentation/tutorials/1.9/dojo_config/demo" } ], // Timeout after 10 seconds waitSeconds: 10, aliases: [ // Instead of having to type "dojo/domReady!", we just want "ready!" instead ["ready", "dojo/domReady"] ], // Get "fresh" resources cacheBust: true }; </script> <script src=""></script> <script> require(["demo/AuthoredDialog", "dojo/parser", "ready!"], function(AuthoredDialog, parser) { // Parse the page parser.parse(); // Do something with demo/AuthoredDialog... }); </script>
  20. 20. Where to start Dojo from? <html> <head> <title>Welcome to Dojo 1.9 </title> <script src="//" data-dojo-config="async: true"></script> </head> <body> <h1 id="Welcome">Welcome to Dojo Toolkit 1.9</h1> </body> </html>
  21. 21. What is AMD? • The Asynchronous Module Definition (AMD) API specifies a mechanism for defining modules • Using AMD the module and its dependencies can be asynchronously loaded. • This is particularly well suited for the browser environment where synchronous loading of modules incurs performance, usability, debugging, and crossdomain access problems.
  22. 22. What is AMD? • The AMD API is the preferred loader API and is exposed through two global functions, require and define. Both functions are normally asynchronous. When running in legacy loader API mode, however, they may operate synchronously in order to allow AMD modules to be accessed by legacy code. • In order to actually require and define modules for use, two global functions are provided by the loader • define, which is used to define a module. • require, which is used to load one or more modules • require is used to configure the loader and load AMD modules. It has the following signature: • require( configuration, // (optional; object) configuration object dependencies, // (optional; array of strings) list of module identifiers to load before calling callback callback // (optional; function) function to call when dependencies are loaded ) -> undefined
  23. 23. What is AMD? • define is very similar to require and is used to define AMD modules. It has the following signature: • define( moduleId, // (optional; string) an explicit module identifier naming the module being defined dependencies, // (optional; array of strings) list of module identifiers to load before calling factory factory // (function or value) the value of the module, or a function that returns the value of the module ) • Module creation is lazy and asynchronous, and does not occur immediately when define is called.
  24. 24. What is AMD? • Once a module value has been entered into the module namespace, it is not recomputed each time it is demanded. • Plugins can be used to extend the loader to support loading resources other than AMD modules: • dojo/domReady, dojo/text, dojo/i18n, dojo/has, dojo/sniff, dojo/require • When a module identifier passed to require or define contains an "!", the loader splits the string in two at the exclamation point. The string to the left of "!" is treated like a normal module ID and is used as the identifier for the desired plugin; the string to the right of "!" is passed to the plugin for processing.
  25. 25. How to define module demo/myModule in file demo/myModule.js? define(["dojo/dom" ], function(dom){ var oldText = {}; return { setText: function(id, text){ var node = dom.byId(id); oldText[id] = node.innerHTML; node.innerHTML = text; }, restoreText: function(id){ var node = dom.byId(id); node.innerHTML = oldText[id]; delete oldText[id]; } }; });
  26. 26. How to require module demo/myModule? • Now that we’ve defined this module, we can load and use it in some actual code // Require the module we just created require(["demo/myModule"], function(myModule){ // Use our module to change the text in the greeting myModule.setText("greeting", "Hello Dojo!"); // After a few seconds, restore the text to its original state setTimeout(function(){ myModule.restoreText("greeting"); }, 3000); });
  27. 27. Is dojo supporting OOPS? • dojo/_base/declare module is the foundation of class creation • The declare function is defined in the dojo/_base/declare module. declare accepts three arguments: className, superClass, and properties. // Create a new class named "mynamespace.MyClass" declare("mynamespace.MyClass", null, { // Custom properties and methods here });
  28. 28. How is inheritance done in Dojo? • Declare with null or other class as first argument assumes there is no class extended var MySubClass = declare(MyClass, { var MyClass = declare(null, { // Custom properties and methods here // MySubClass now has all of MyClass's properties and methods // These properties and methods override parent's }); });
  29. 29. Does dojo support Multiple Inheritance? • array of classes signifies multiple inheritance var MyMultiSubClass = declare([ MySubClass, MyOtherClass, MyMixinClass ],{ // MyMultiSubClass now has all of the properties and methods from: // MySubClass, MyOtherClass, and MyMixinClass });
  30. 30. How to create a simple class with inheritance? define([ "dojo/_base/declare", "dijit/form/Button" ], function(declare, Button){ return declare("mynamespace.Button", Button, { label: "My Button", onClick: function(evt){ console.log("I was clicked!"); this.inherited(arguments); } }); });
  31. 31. How to write a constructor in Dojo? // Create a new class var Twitter = declare(null, { // The default username username: "defaultUser", // The constructor constructor: function(args){ declare.safeMixin(this,args); } });
  32. 32. How to theme in Dojo? • • Dijit includes a theming framework that allows a user to define. Dijit includes four themes to choose from: Claro, Tundra, Soria, and Nihilo. • • Include the theme css file <link rel="stylesheet" href=""> • Include the theme class name in the body tag <body class="claro"> <h1 id="greeting">Hello</h1> </body>
  33. 33. How to use Dojo to manipulate the DOM in a simple, cross-browser way? • As far as browser-based JavaScript is concerned, the Document Object Model (DOM) is the glass that we paint. • Dojo aims to make working with the DOM easy and efficient. • Provides a handful of convenience functions that fill some awkward cross-browser incompatibilities and make common operations simpler and less verbose. • There are four operations of Javascript on DOM using Dojo : – – – – Retrieval Creation Placement Destruction
  34. 34. How to use Dojo to manipulate the DOM in a simple, cross-browser way? • We need to know how to get elements from the DOM, in order to work with them. • Dojo provides dojo/dom resource's byId method . • When you pass an ID to dom.byId, you will receive the DOM node object with that ID. • If no matching node is found, a null value will be returned. • This is the equivalent of using document.getElementById, but with two advantages. – It is shorter to type.  – It works around some browsers' buggy implementations of getElementById
  35. 35. How to use Dojo to manipulate the DOM in a simple, cross-browser way(Retrieval)? require(["dojo/dom", "dojo/domReady!"], function(dom) { function setText(node, text){ node = dom.byId(node); node.innerHTML = text; } var one = dom.byId("one"); setText(one, "One has been set"); setText("two", "Two has been set as well"); });
  36. 36. How to use Dojo to manipulate the DOM in a simple, cross-browser way(Creation)? • Dojo’s dojo/dom-construct's create method a more convenient and reliable option. • The arguments to domConstruct.create are as follows – node name as a string, – properties of the node as an object, – an optional parent or sibling node, – and an optional position in reference to the parent or sibling node (which defaults to "last"). •
  37. 37. How to use Dojo to manipulate the DOM in a simple, cross-browser way(Creation)? require(["dojo/dom", "dojo/dom-construct", "dojo/domReady!"], function(dom, domConstruct) { var list = dom.byId("list"); domConstruct.create("li", { innerHTML: "Six“ }, list); });
  38. 38. How to use Dojo to manipulate the DOM in a simple, cross-browser way(Placement)? • Dojo’s dojo/dom-construct's place method is used to place the node. – – – – The arguments to are as follows A DOM node or string ID of a node to place. A DOM node or string ID of a node to use as a reference. An optional position as a string which defaults to "last" if not provided. Options (before,after,first) • domConstruct.create uses under the hood.
  39. 39. How to use Dojo to manipulate the DOM in a simple, cross-browser way(Destruction)? • To remove nodes dojo provides two ways : – domConstruct.destroy which will destroy a node and all of its children. – domConstruct.empty will only destroy the children of a given node. • Both take a DOM node or a string ID of a node as their only argument.
  40. 40. How to use Dojo to manipulate the DOM in a simple, cross-browser way(Destruction)? require(["dojo/dom", "dojo/domconstruct", "dojo/domReady!"], domConstruct.destroy("list"); domConstruct.empty("list"); });
  41. 41. How to query a DOM? • It's important to be able to retrieve nodes quickly and efficiently. • Covered one option dom.byId. However, coming up with unique IDs for every node in your application can be a daunting and impractical task. • It would also be inefficient to find and operate on multiple nodes by ID alone. • The dojo/query module uses familiar CSS queries (which you use in your stylesheets) to retrieve a list of nodes, including support for advanced CSS3 selectors! • Require the query module in dependency array to work with query in Dojo.
  42. 42. How to query a DOM? require(["dojo/query", "dojo/domReady!"], function(query) { // retrieve an array of nodes with the ID “username" var usrName = query(“#userName“)*0+; }) <input type=“text” id=“userName” value=“Predhin”/>
  43. 43. How to query a DOM? • retrieve an array of nodes with the class name "odd" var odds = query(".odd"); • // retrieve an array of nodes with the class name "odd" from the first a particular id “list” using a selector var odds1 = query("#list .odd"); • // Retrieve an array of any a element that has an li as its ancestor. var allA = query("li a"); • // Retrieve an array of any a element that has an li as its direct ancestor. var someA = query("li > a");
  44. 44. How to query a DOM? • NodeList has methods that match the Dojo array helper methods. One such method is forEach. query(".odd").forEach(function(node, index, nodelist){ // for each node in the array returned by query, // execute the following code domClass.add(node, "red"); }); • Where node is the current node, Index of the current node, nodelist is the entire set of selected nodes.
  45. 45. How to query a DOM(Node List Extensions)? • Because each query call returns a NodeList, we can make this even simpler by chaining method calls query("li.fresh").on("click", function(evt){ alert("I love fresh " + this.innerHTML); });
  46. 46. How to query a DOM(Node List DOM Extensions)? • The dojo/Nodelist-dom contains DOM methods such as addClass, removeClass, attr, style, empty, and place which work on NodeList. require(["dojo/query", "dojo/NodeList-dom"], function(query) { query("li.fresh") .addClass("fresher") .attr("title", "freshened") .style("background", "lightblue") .on("click", function(evt){ alert("I love fresh " + this.innerHTML); }); });
  47. 47. How to query a DOM(Animating)? • The dojo/NodeList-fx module augments NodeList with a series of methods that allow you to apply effects from Dojo’s effects system to a collection of nodes. require(["dojo/query", "dojo/NodeList-fx", "dojo/domReady!"], function(query) { query("#btn").on("click", function(){ query("li.fresh") .slideTo({ left: 200, auto: true }) .animateProperty({ properties: { backgroundColor: { start: "#fff", end: "#ffc" } } }) .play(); }); });
  48. 48. How to query a DOM(Add data to DOM)? • The dojo/NodeList-data module adds a mechanism for attaching arbitrary data to elements via the data method require(["dojo/query", "dojo/NodeList-data", "dojo/domReady!"], function(query, NodeList) { function mark(evt){ var nodeList = new NodeList(this); // make a new NodeList from the clicked element"updated", new Date()); // update the 'updated' key for this element via the NodeList } query("li") // get all list items .data("updated", new Date()) // set the initial data for each matching element .on("click", mark); // add the event handler query("#btn").on("click", function(){ query("li").data("updated").forEach(function(date){ console.log(date.getTime()); }); }); });
  49. 49. How to query a DOM(Add data to DOM)? • • • no automatic node-deletion tracking going on. If you bind data to a node, and destroy that node directly or indirectly, the data will persist in the cache call _gcNodeData() at any time. It will remove items from the cache for nodes that no longer exist in the DOM highly recommended you manually manage your Data items if in a scenario leading to these potential “leaks”. • require(["dojo/_base/kernel", "dojo/NodeList-data"], function(kernel){ kernel._gcNodeData(); });
  50. 50. How to attach events in Dojo? • dojo/on module provides methods to register events. • require(["dojo/on", "dojo/dom", "dojo/dom-style", "dojo/mouse", "dojo/domReady!"], function(on, dom, domStyle, mouse) { var myButton = dom.byId("myButton"), myDiv = dom.byId("myDiv"); on(myButton, "click", function(evt){ domStyle.set(myDiv, "backgroundColor", "blue"); }); on(myDiv, mouse.enter, function(evt){ domStyle.set(myDiv, "backgroundColor", "red"); }); });
  51. 51. How to attach events in Dojo? • The on method not only normalizes the API to register events, but it also normalizes how event handlers work: • Event handlers are always called in the order they are registered. • They are always called with an event object as their first parameter. • The event object will always be normalized to include common W3C event object properties, including things like a target property, a stopPropagation method, and a preventDefault method. • Dojo also provides a way to remove an event handler: handle.remove
  52. 52. How to attach events in Dojo? var handle = on(myButton, "click", function(evt){ // Remove this event using the handle handle.remove(); // Do other stuff here that you only want to happen one time alert("This alert will only happen one time."); }); • dojo/on includes a convenience method for doing exactly this: on.once. • It accepts the same parameters as on, but will automatically remove the handler once it is fired.
  53. 53. How to attach events in Dojo? • By default, on will run event handlers in the context of the node passed in the first argument. • • lang.hitch (from the dojo/_base/lang module) to specify the context in which to run the handler. require(["dojo/on"], function(on){ var processEvent = function(e){ this.something = "else"; }; on(something, "click", processEvent); });
  54. 54. How to attach events in Dojo? • In asynchronous callbacks such as above, the context that the code is executing in has changed. It will no longer refer to the object that originally provided it require(["dojo/on", "dojo/_base/lang"], function(on, lang){ var processEvent = function(e){ this.something = "else"; }; on(something, "click", lang.hitch(this, processEvent)); });
  55. 55. How to use event deligation in Dojo? • Event delegation using the dojo/on module, using the syntax on(parent element, "selector:event name", handler). • dojo/on needs a selector engine exposed by dojo/query in order to be able to match selectors used for event delegation <div id="parentDiv"> <button id="button1" class="clickMe">Click me</button> <button id="button2" class="clickMe">Click me also</button> </div> <script> require(["dojo/on", "dojo/dom", "dojo/query", "dojo/domReady!"], function(on, dom){ var myObject = { id: "myObject", onClick: function(evt){ alert("The scope of this handler is " +; } }; var div = dom.byId("parentDiv"); on(div, ".clickMe:click", myObject.onClick); }); </script>
  56. 56. How to use event delegation in Dojo? • • • • • • • • • • • • "click" - the user clicked a node "focus" - a node received focus "blur" - a node was 'blurred', or otherwise lost focus "change" - an input value was changed "keypress" - fired when the user presses a key that displays "keydown" - fired for non-printable keys "keyup" - fired when the user releases a key "mouseover" - a node was hovered (warning: may fire more than you'd like because of bubbling) "mouseout" - a node was un-hovered dojo/mouse#enter - a normalized version of onmouseover that wont fire more than you'd like (only on first enter) dojo/mouse#leave - a normalized version of onmouseout that wont fire more than you'd like (only once when leaving) submit - a form has been submitted
  57. 57. How to add effects in Dojo? • Dojo provides effects, which allow us to jazz up your page or application! • Dojo 1.9 has two fx modules: dojo/_base/fx and dojo/fx. • dojo/_base/fx provides base effects methods that were found previously in Dojo base, including: animateProperty, anim, fadeIn, and fadeOut. • dojo/fx provides more advanced effects, including: chain, combine, wipeIn, wipeOut and slideTo
  58. 58. How to add effects in Dojo(fade)? • • • One animation you might have seen in applications you have used is a node fading in or out. This effect is so common and simple that it's included as a part of the Dojo base. Used it to hide or show elements on a page in a way that feels really smooth and polished. <button id="fadeOutButton">Fade block out</button> <button id="fadeInButton">Fade block in</button> <div id="fadeTarget" class="red-block"> A red block </div> <script> require(["dojo/_base/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) { var fadeOutButton = dom.byId("fadeOutButton"), fadeInButton = dom.byId("fadeInButton"), fadeTarget = dom.byId("fadeTarget"); on(fadeOutButton, "click", function(evt){ fx.fadeOut({ node: fadeTarget }).play(); }); on(fadeInButton, "click", function(evt){ fx.fadeIn({ node: fadeTarget }).play(); }); }); </script>
  59. 59. How to add effects in Dojo(wipe)? • • • Changing the height of a node while leaving the content alone. This makes it look like someone is using a windshield wiper on the node. Used it to hide or show elements on a page in a way that feels really smooth and polished. <script> require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) { on(wipeOutButton, "click", function(evt){ fx.wipeOut({ node: wipeTarget }).play(); }); on(wipeInButton, "click", function(evt){ fx.wipeIn({ node: wipeTarget }).play(); }); }); </script>
  60. 60. How to add effects in Dojo(slide)? • • Shifting a node around to create an appearance of movement or progression on a page. fx.slideTo creates a smooth animation of the node in the page, moving it around by specifying the coordinates of the top and left position of the node in pixels. <script> require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) { on(slideAwayButton, "click", function(evt){ fx.slideTo({ node: slideTarget, left: "200", top: "200" }).play(); }); on(slideBackButton, "click", function(evt){ fx.slideTo({ node: slideTarget, left: "0", top: "100" }).play(); }); }); </script> </script>
  61. 61. How to handle animation events in Dojo? • • • All of these animation methods discussed previously return a dojo.Animation object. These objects all provide controls to play or pause the animation. Provide a set of events that we can listen to, in order to perform some sorts of actions before, during, and after the animation. on(slideAwayButton, "click", function(evt){ var anim = fx.slideTo({ node: slideTarget, left: "200", top: "200", beforeBegin: function(){ style.set(slideTarget, { left: "0px", top: "100px" }); } }); on(anim, "End", function(){ style.set(slideTarget, { backgroundColor: "blue“ }); }, true);; });
  62. 62. How to chain effects in Dojo? • • dojo/fx module gives us a couple of great convenience methods to set up effects to run in sequence or in parallel. fx.chain is used to play animations one after another. require(["dojo/_base/fx", "dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, fx, on, dom) { on(slideAwayButton, "click", function(evt){ fx.chain([ baseFx.fadeIn({ node: slideTarget }), fx.slideTo({ node: slideTarget, left: "200", top: "200" }), baseFx.fadeOut({ node: slideTarget }) ]).play(); }); });
  63. 63. How to combine effects in Dojo? • dojo/fx provides is the combine method which will start multiple animations at the same time. require(["dojo/_base/fx", "dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, fx, on, dom) { on(slideAwayButton, "click", function(evt){ fx.combine([ baseFx.fadeIn({ node: slideTarget }), fx.slideTo({ node: slideTarget, left: "200", top: "200" }) ]).play(); }); });
  64. 64. How to create custom effects in Dojo? • • Using Dojo we can create and combine effects for customized animation of elements on the page. Dojo's generic animation utility, baseFx.animateProperty is used for this purpose. require(["dojo/_base/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, on, dom) { baseFx.animateProperty({ node: anim8target, properties: { top: : { start: 25, end: 150 }, left: 0, opacity: { start: 1, end: 0 } }, duration: 800 }).play(); });
  65. 65. What is Dijit? • Dijit is both a framework for defining user interface widgets, and a collection of ready-to-use controls and related functionality. • It enhances native controls like form fields, provides widgets for dynamic layouts and advanced widgets like trees and calendars. • The dijit package is a sibling to Dojo Core. It is managed and run as a sub-project of the Dojo Toolkit, with its own owner, policies and guidelines
  66. 66. What is Dijit? • Dijit also has powerful tools for creating dynamic user interfaces that adapt to viewport size, and respond to resize and user interaction • It includes widgets for creating desktop-like application layouts and standard items like Tab and Accordion controls for making the best use of the space available. •
  67. 67. What is Dijit? • Can use Dijit in one of two ways: – declaratively by using special attributes inside of regular HTML tags – programmatically through JavaScript require(["dijit/Dialog", "dojo/domReady!"], function(Dialog){ // create a "hidden" Dialog: var myDialog = new Dialog({ title:"Hello Dijit!" }, "someId"); myDialog.startup(); // Hint: In order to open the dialog, you have to call; });
  68. 68. What is Dijit? • is identical to: <script> require(["dojo/parser", "dijit/Dialog"]); </script> <div data-dojo-type="dijit/Dialog" title="Hello Dijit!" id="someId"></div> • The declarative method requires you include the dojo/parser and have either dojoConfig.parseOnLoadset to true, or you manually call parser.parse() when you would like the widgets (aka: Dijits) to be created.
  69. 69. What is Dijit? • Dijit uses a special function for access, dijit.byId() ... This is not the same as dojo.byId, which works exclusively on DomNodes. Dijit stores all active widgets in the dijit/registry, and uses id’s as unique qualifiers. registry.byId() returns the instance (widget) from a passed ID, allowing you access to all the methods and properties within: <script> require(["dojo/parser", "dijit/registry", "dojo/dom", "dojo/domReady!"], function(parser, registry, dom){ parser.parse(); // dom.byId("foobar") would only be a normal domNode. var myDialog = registry.byId("foobar"); myDialog.set("content", "<p>I've been replaced!</p>");; }); </script> <div data-dojo-type="dijit/Dialog" id="foobar" title="Foo!"> <p>I am some content</p> </div>
  70. 70. What is Dijit? • When creating widgets programmatically, pass an id:”” parameter, Otherwise, a unique ID will be generated. • All Dijits follow the same programmatic convention. Create a new instance with the JavaScript new function, pass an object-hash of properties and functions (in this case, title:”No ID”), and supply an optional “source node reference”. require(["dijit/Dialog", "dojo/dom"], function(Dialog, dom){ var node = dom.byId("makeADialog"); var myDialog = new Dialog({ title:"From Source Node" }, node);; });
  71. 71. How to create a dijit button? • dijit/form/Button the most basic widget in any toolkit is a button. • Allows a user to trigger an action, such as submitting a form or resetting the values on a form. Some Widget properties • – – – – iconClass: indicates what CSS class to use (to apply an image sprite). showLabel: determines whether to show any text in the button. title: sets the value of the HTML title attribute on the rendered DOM node of the widget. label: in programmatic usage, this indicates the content of the button label; declaratively, this is specified via the content (innerHTML) of the element representing the widget. <button id="btn2" data-dojo-type="dijit.form.Button“ data-dojo-props=“ iconClass:'dijitIconNewTask', showLabel:false, onClick:function(){}"> Click Me! </button>
  72. 72. How to create a dijit button? • Dijit also includes three other button widgets: • dijit/form/ToggleButton: a button that maintains an on/off state. • dijit/form/DropDownButton: a button designed to show a popup widget (such as a menu) when clicked. • dijit/form/ComboButton: like a dijit/form/Button
  73. 73. How to create a dijit textbox? • dijit/form namespace, there are a number of textboxbased widgets • dijit/form/TextBox: a basic textbox . • dijit/form/SimpleTextarea: a basic textarea, for large text input. • dijit/form/ValidationTextBox: a textbox with basic validation abilities, which can be further customized. • dijit/form/NumberTextBox: a textbox that ensures the input is numeric. • dijit/form/DateTextBox: a textbox that includes a popup calendar.
  74. 74. How to create a dijit textbox? • dijit/form/TimeTextBox: a textbox that includes a popup time-picker. • dijit/form/CurrencyTextBox: an extension of dijit/form/NumberTextBox with additional considerations for localized currency. • dijit/form/NumberSpinner: an extension of dijit/form/NumberTextBox providing buttons and keybindings for incrementally changing the value. • dijit/form/Textarea: an extension of dijit/form/SimpleTextarea which dynamically increases or decreases its height based on the amount of content inside.
  75. 75. What is Dojox? • The dojox namespace is a collection of sub-projects that extend the toolkit into common and less common areas • Examples – DojoX: Data Grid
  76. 76. What is Dojox? • • • • • • There are several different statuses for sub-packages and modules: Mature - This package or module is considered mature and is being actively developed and maintained by committers within the Dojo Toolkit. It is expected that it will persist into the foreseeable future. Experimental - This package or module is experimental, while it is being actively developed and maintained, the API may change in the future and developers should be cautious about depending on the API remaining unchanged or the code continuing to persist in the future. Maintained - This code is being actively maintained, but may or may not persist into Dojo 2.0. Deprecated - This code is being actively maintained for backwards compatibility purposes, but a decision has been made that this package will not persist into Dojo 2.0. Abandoned - This code is not being actively maintained anymore. End developers may have difficulty using this code in current and future versions of the Dojo Toolkit. Patches are usually welcome for bug fixes, but it is highly unlikely new features or enhancements will be considered.
  77. 77. What is Dojox? – DojoX: Charting • DojoX historically was an area for development of additional Dojo functionality. •
  78. 78. How to create a chart in Dojo? <div id="simplechart" style="width: 250px; height: 150px; margin: 5px auto 0px auto;"></div> --------------------------------------------------------------------------------------------------------require(["dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Lines", "dojo/ready"], function(Chart, Default, Lines, ready){ ready(function(){ var chart1 = new Chart("simplechart"); chart1.addPlot("default", {type: Lines}); chart1.addAxis("x"); chart1.addAxis("y", {vertical: true}); chart1.addSeries("Series 1", [1, 2, 2, 3, 4, 5, 5, 7]); chart1.render(); }); });
  79. 79. How to represent a grid data in Dojo? • The dojox/grid/DataGrid is the central component of many applications due to its effective and usable presentation of tabular data. • DataGrid is made up of several different parts.(dgrid is recommended over DataGrid) • At the highest level, a DataGrid is made up of views. • Views break the DataGrid up into sections and render the header and content for each section. • Headers and contents contain rows (although the header only contains one row) which are populated by sub-rows of cells. •
  80. 80. How to represent a grid data in Dojo? • • • Cells tell the DataGrid what cells, or columns, we want to be displayed for each data record. we will pass an array of cell definition objects to the structure property. Each cell definition object can have several properties defined: – – – – • name: the string to use in the header cell field: the name of the field of the data record to display width: a string containing the CSS width (with units) of the column hidden: a boolean that when true will hide the column The cell definition properties headerStyles, cellStyles, and styles are strings of CSS style definitions. var grid = new DataGrid({ store: store, query: { id: "*" }, structure: [ { name: "First Name", field: "first", width: "84px" }, { name: "Last Name", field: "last", width: "84px" }, { name: "Bats", field: "bats", width: "70px" }, ………… ] }, "grid");
  81. 81. How to represent a grid data in Dojo? var employees = [ {name:"Jim", department:"accounting"}, {name:"Bill", department:"engineering"}, {name:"Mike", department:"sales"}, {name:"John", department:"sales"} ]; require([ "dojox/grid/DataGrid", "dojo/data/ObjectStore", "dojo/domReady!”+, function(DataGrid, ObjectStore){ grid = new DataGrid({ store: new ObjectStore({objectStore: employees}), structure: [ {name:"State Name", field:"name", width: "200px"}, {name:“Department", field:“department", width: "200px"} ] }, "target-node-id"); // make sure you have a target HTML element with this id grid.startup(); });
  82. 82. What are the layouts in Dojo? • Dojo picks up with a set of extensible widgets as a part of Dijit - Dojo's UI framework. • Layouts allow precise placement and management of areas of the page where we want to: • Respond to resize events • Provide for user control over layout and how the available space is apportioned • Adapt controls and/or contents to the currently available horizontal and vertical space • Some layout widgets – – – – AccordianContainer( BorderContainer( StackContainer( TabContainer(
  83. 83. What are the layouts in Dojo? • Widgets can be created declaratively or programmatically. <div class="centerPanel” data-dojo-type="dijit.layout.TabContainer” data-dojo-props="region: 'center', tabPosition: 'bottom'"> <div data-dojo-type="dijit.layout.ContentPane” data-dojo-props="title: 'Group 1'"> <h4>Group 1 Content</h4> </div> </div> -------------------------------------------------------------------------------------------------------------------------------------------var contentTabs = new TabContainer({ region: "center", id: "contentTabs", tabPosition: "bottom", "class": "centerPanel", href: "contentCenter.html" }) var contentPane = new ContentPane(,“title”:”Group 1”,”content”:” <h4>Group 1 Content</h4> ”-) contentTabs.addChild(contentPane ); contentTabs.startup();
  84. 84. What are the layouts in Dojo? • • • • • • dijit/layout/BorderContainer allows you to define a layout subdivided into regions. The center region is always flexible and auto-sized. Other regions are fixed in size: "top", "bottom", "leading", "trailing", "left" or "right". Each region is represented by a child widget. All Dijit widgets support the region property, so in principle, you can use any widget in these positions. The fixed-size regions (all but center) can have a end-user-moveable divider associated with them by setting a splitter property.
  85. 85. What are the layouts in Dojo? • dijit.layout.TabContainer is a container that has multiple panes, but shows only one pane at a time. • There are a set of tabs corresponding to each pane. • Each tab has the title (aka label) of the pane, and optionally a close button.
  86. 86. What are the different stores in Dojo? • is the API for Stores • Different types of Store – Memory(dojo/store/Memory) – Observable(dojo/store/Observable) – Object(dojo/data/ObjectStore) – JSON(dojo/store/JsonRest) – XML(dojo/data/XMLStore) – Cache(dojo/store/Cache)
  87. 87. How to use memory in Dojo? • Memory store provides full read and write capabilities for in memory data • synchronous store(directly returns the results of an action (get returns the object)) • Memory store uses the dojo/store/util/SimpleQueryEngine
  88. 88. How to use memory in Dojo? require(["dojo/store/Memory"], function(Memory){ var someData = [ {id:1, name:"One"}, {id:2, name:"Two"} ]; store = new Memory({data: someData}); store.get(1) -> Returns the object with an id of 1 store.query({name:"One"}) // Returns query results from the array that match the given query store.query(function(object){ return > 1; }) // Pass a function to do more complex querying store.query({name:"One"}, {sort: [{attribute: "id"}]}) // Returns query results and sort by id store.put({id:3, name:"Three"}); // store the object with the given identity store.remove(3); // delete the object });
  89. 89. How to use Observable in Dojo? • dojo/store/Observable is an object store wrapper that adds support for notification of data changes to query result sets • The observe function provides indication of the previous and new index values of changed objects to properly update result arrays.
  90. 90. How to use Observable in Dojo? require(["dojo/store/Observable", "dojo/store/Memory"], function(Observable, Memory){ // create the initial Observable store store = new Observable(new Memory({data: someData})); // query the store var results = store.query({rating:5}); // do something with the initial result set results.forEach(insertRow); // now listen for any changes var observeHandle = results.observe(function(object, removedFrom, insertedInto){ if(removedFrom > -1){ // existing object removed removeRow(removedFrom); } if(insertedInto > -1){ // new or updated object inserted insertRow(insertedInto, object); } }); // this will trigger an addition to the result set (the observe listener will be called) store.put({rating: 5, id: 3}); // this will *not* trigger a observe event, since the object does not match the query constraint (query was for rating = 5) store.put({rating: 3, id: 4}); // if this object was in the result set, it will trigger a observe event store.remove(2); // done observing, any further modifications will not trigger our listener observeHandle.cancel(); });
  91. 91. How to use ObjectStore in Dojo? • is an adapter for using the new Dojo Object Stores var jsonStore = new{target:"/Table/"}); var dataStore = new{objectStore: jsonStore }); // we can now use dataStore with any legacy Dojo Data consumer var grid = new{ store: dataStore, ... });
  92. 92. How to use JSONStore in Dojo? • store actions to your server using standards-based HTTP/REST with JSON • store actions map intuitively to HTTP GET, PUT, POST, and DELETE methods. require(["dojo/store/JsonRest"], function(JsonRest){ employeeStore = new JsonRest({target:"/Employee/"}); employeeStore.get("Bill").then(function(bill){ // called once Bill was retrieved }); });
  93. 93. How to use XMLStore in Dojo? • XmlStore is a read and write interface to basic XML data var store = new{url: "books.xml", rootItem: "book"}); var gotBooks = function(items, request){ for(var i = 0; i < items.length; i++){ var item = items[i]; console.log("Located book: " + store.getValue(item, "title"); } } var request = store.fetch({query: {isbn:"A9B57*"}, onComplete: gotBooks});
  94. 94. How to use CacheStore in Dojo? • The Cache store provides caching capabilities for stores. • usage of dojo/store/Cache would be to use a JsonRest store as the master store, and a Memory store as the caching store. restStore = new JsonRest(...); memoryStore = new Memory(); store = new Cache(restStore, memoryStore); store.get(1) -> Returns the object with an id of 1 by making a GET request store.get(1) -> Returns the object, using the local memory cache store.put({id:2, name:"two"}) -> Stores the object in both master and cache store store.get(2) -> Returns the object, using the local memory cache
  95. 95. How to populate a combobox? require([ "dojo/store/Memory", "dijit/form/ComboBox", "dojo/domReady!" ], function(Memory, ComboBox){ var stateStore = new Memory({ data: [ {name:"Alabama", id:"AL"}, {name:"Alaska", id:"AK"}, {name:"American Samoa", id:"AS"}, {name:"Arizona", id:"AZ"}, {name:"Arkansas", id:"AR"}, {name:"Armed Forces Europe", id:"AE"}, {name:"Armed Forces Pacific", id:"AP"}, {name:"Armed Forces the Americas", id:"AA"}, {name:"California", id:"CA"}, {name:"Colorado", id:"CO"}, {name:"Connecticut", id:"CT"}, {name:"Delaware", id:"DE"} ] }); var comboBox = new ComboBox({ id: "stateSelect", name: "state", value: "California", store: stateStore, searchAttr: "name" }, "stateSelect"); }); -----------------------------------------------------------------------------------------------------------------------<input id="stateSelect"> <p><button onClick="alert(dijit.byId('stateSelect').get('value'))">Get value</button></p>
  96. 96. How to create a custom widget in Dojo? • Dijit's _Widget and _WidgetBase provide a fantastic foundation for creating widgets, but the _Templated mixin is where Dijit really shines. • With _Templated, you can quickly create widgets that are highly maintainable, quickly modifiable and easy to manipulate. • The basic concept of _Templated is simple enough: • It allows a developer to create a small HTML file that has a few small extensions loads this HTML file as a string at run-time (or inlined during the build process) for re-use by all instances of the templated widget.
  97. 97. How to create a custom widget in Dojo? • • als/1.9/recipes/custom_widget/
  98. 98. What is the life cycle of custom Widget? • The lifecycle of a widget describes the phases of its creation and destruction which you can hook into. It’s useful to understand exactly what happens when. Whether you are sub-classing an existing widget, using dojo/method script blocks, or passing in method overrides to the constructor, these are your entry points for making a widget do what you want it to do. – – – – – – – – – Widgets are classes, created with dojo.declare. All widgets inherit from dijit._WidgetBase, and most get the _Templated mixin. That provides you the following extension points (methods) you can override and provide implementation for: constructorYour constructor method will be called before the parameters are mixed into the widget, and can be used to initialize arrays, etc. parameters are mixed into the widget instanceThis is when attributes in the markup (ex: <button iconClass=...>) are mixed in or, if you are instantiating directly, the properties object you passed into the constructor (ex: new dijit.form.Button(,label: “hi”-)). This step itself is not overridable, but you can play with the result in... postMixInPropertiesIf you provide a postMixInProperties method for your widget, it will be invoked before rendering occurs, and before any dom nodes are created. If you need to add or change the instance’s properties before the widget is rendered this is the place to do it. buildRenderingdijit._Templated provides an implementation of buildRendering that most times will do what you need. The template is fetched/read, nodes created and events hooked up during buildRendering. The end result is assigned to this.domNode. If you don’t mixindijit._Templated (and most OOTB dijits do) and want to handle rendering yourself (e.g. to really streamline a simple widget, or even use a different templating system) this is where you’d do it. setters are calledSetters are called for all attributes with custom setters and that were either specified as constructor parameters or have non-null non-blank non-zero default values. postCreateThis is typically the workhorse of a custom widget. The widget has been rendered (but note that child widgets in the containerNode have not!). The widget though may not be attached to the DOM yet so you shouldn’t do any sizing calculations in this method. startupIf you need to be sure parsing and creation of any child widgets has completed, use startup. This is often used for layout widgets like BorderContainer. If the widget does JS sizing, then startup() should call resize(), which does the sizing. destroyImplement destroy if you have special tear-down work to do (the superclasses will take care of most of it for you. Examples on how to destroy a widget:
  99. 99. How to extend a dijit Widget? declare("my/Button", dijit.form.Button, { xyz: '', buildRendering: function() { this.inherited(arguments); this.domNode.setAttribute("xyz",; } }); -----------------------------------------------------------------------------------------<div dojoType="my/Button" xyz="foobar" id="mybtn"></div>
  100. 100. How to create a custom widget in Dojo? require([ "dojo/_base/declare", "dojo/parser", "dojo/ready", "dijit/_WidgetBase", ], function(declare, parser, ready, _WidgetBase){ declare("MyFirstBehavioralWidget", [_WidgetBase], { // put methods, attributes, etc. here }); ready(function(){ // Call the parser manually so it runs after our widget is defined, and page has finished loading parser.parse(); }); }); -----------------------------------------------------------------------------------------------------------Instantiate the widget in markup -----------------------------------------------------------------------------------------------------------<span data-dojo-type="MyFirstBehavioralWidget">hi</span>
  101. 101. How to create a custom widget in Dojo? require([ "dojo/_base/declare", "dojo/dom-construct", "dojo/parser", "dojo/ready",”dojo/on”, "dijit/_WidgetBase", ], function(declare, domConstruct, parser, ready, on,_WidgetBase){ declare("Counter", [_WidgetBase], { // counter _i: 0, buildRendering: function(){ // create the DOM for this widget this.domNode = domConstruct.create("button", {innerHTML: this._i}); }, postCreate: function(){ // every time the user clicks the button, increment the counter on(this.domNode, "onclick", "increment"); }, increment: function(){ this.domNode.innerHTML = ++this._i; } }); ready(function(){ // Call the parser manually so it runs after our widget is defined, and page has finished loading parser.parse(); }); }); Instantiate declaratively: <span data-dojo-type="Counter"></span>
  102. 102. How to create a custom widget in Dojo? require([ "dojo/_base/declare", "dojo/parser", "dojo/ready", "dijit/_WidgetBase", "dijit/_TemplatedMixin" ], function(declare, parser, ready, _WidgetBase, _TemplatedMixin){ declare("FancyCounter", [_WidgetBase, _TemplatedMixin], { // counter _i: 0, templateString: "<div>" + "<button data-dojo-attach-event='onclick: increment'>press me</button>" + "&nbsp; count: <span data-dojo-attach-point='counter'>0</span>" + "</div>", increment: function(){ this.counter.innerHTML = ++this._i; } }); ready(function(){ // Call the parser manually so it runs after our widget is defined, and page has finished loading parser.parse(); }); }); -------------------------------------------------------------------------------------------------------------<span data-dojo-type="FancyCounter">press me</span>
  103. 103. How to create a custom widget in Dojo? • Case of widget inside of the template: <div class="combinedDateTime"> <div data-dojo-type="dijit/form/DateTextBox"></div> <div data-dojo-type="dijit/form/TimeTextBox"></div> </div> • When using this template in a directly extended widget class, you will need to mixin dijit._WidgetsInTemplateMixin in addition to dijit._TemplatedMixin.
  104. 104. How to create a custom widget in Dojo? • What _Templated Provides – templateString, // a string representing the HTML of the template – widgetsInTemplate // a Boolean indicating whether or not child widgets are defined in the template • In addition to the properties above, _Templated overrides three methods defined in Dijit's widget architecture: – buildRendering, – destroyRendering, – startup. • • These three methods handle the parsing and filling out of the template (buildRendering), destroying the widget's DOM correctly (destroyRendering), and ensuring that any child widgets in a template are started correct
  105. 105. How to create a custom widget in Dojo? <div class="${baseCls}" data-dojo-attach-point="focusNode" data-dojo-attachevent="ondijitclick:_onClick“ > <span data-dojo-attach-point="containerNode"></span> </div> • This template demonstrates three of the most important aspects of the Dijit template system: variable substitution, attach points, and event attachments. • Variable Substitution – • Attach Points – • Property of the widget to get the corresponding dom element. Event Attachments – • The variable name is any property or field defined in your widget declaration ${property} or ${!} If the property in question happens to be a reference to an object. Dijit template system gives you a way of attaching native DOM events to methods in your custom widget. The widgetsInTemplate Property – This property (by default, set to false) tells the template system that your template has other widgets in it and to instantiate them when your widget is instantiated.
  106. 106. How to create a custom widget in Dojo? Each widget declared with _WidgetBase as its base will run through several methods during instantiation. They are listed here, organized according to the sequence in which they are called: • constructor (common to all prototypes, called when instantiated) • postscript (common to all prototypes built using declare) – – – – • o create + postMixInProperties + buildRendering + postCreate startup
  107. 107. How to create a custom widget in Dojo? postCreate() This is fired after all properties of a widget are defined, and the document fragment representing the widget is created But before the fragment itself is added to the main document. When developing a custom widget, most (if not all) of your customization will occur here. startup() Probably the second-most important method in the Dijit lifecycle is the startup method. This method is designed to handle processing after any DOM fragments have been actually added to the document; it is not fired until after any potential child widgets have been created and started as well
  108. 108. How to use ajax in Dojo? • dojo/request/xhr is a provider that uses XMLHttpRequest (XHR) objects to make asynchronous requests. It is the default provider for browser based platforms. require(["dojo/request/xhr"], function(xhr){ xhr("example.json", { handleAs: "json" }).then(function(data){ // Do something with the handled data }, function(err){ // Handle the error condition }, function(evt){ // Handle a progress event from the request if the // browser supports XHR2 }); });
  109. 109. How to use ajax in Dojo? • dojo/request/xhr takes two arguments – url String The URL that the request should be made to. – options Object? Optional A hash of options. – require(["dojo/request/xhr", "dojo/dom", "dojo/dom-construct", "dojo/json", "dojo/on", "dojo/domReady!"], function(xhr, dom, domConst, JSON, on){ on(dom.byId("startButton"), "click", function(){"<p>Requesting...</p>", "output"); xhr("helloworld.json", { handleAs: "json" }).then(function(data){"<p>response: <code>" + JSON.stringify(data) + "</code></p>", "output"); }); }); }); <h1>Output:</h1> <div id="output"></div> <button type="button" id="startButton">Start</button>
  110. 110. How to use deferred in Dojo? • Powerful tool for working with asynchronous operations, such as Ajax • Deferred waits until a later time to perform an action; essentially, you're deferring the action until a prior action is completed. Ajax is one such situation: We don't want to take some actions until we know that the server has successfully sent information back to us.
  111. 111. How to use deferred in Dojo? require(["dojo/Deferred", "dojo/request", "dojo/_base/array", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"], function(Deferred, request, arrayUtil, domConstruct, dom) { // Create a deferred and get the user list var deferred = new Deferred(), userlist = dom.byId("userlist"); // Set up the callback and errback for the deferred deferred.then(function(res){ arrayUtil.forEach(res, function(user){ domConstruct.create("li", { id:, innerHTML: user.username + ": " + }, userlist); }); },function(err){ domConstruct.create("li", { innerHTML: "Error: " + err }, userlist); }); // Send an HTTP request request.get("users.json", { handleAs: "json"}).then( function(response){ // Resolve when content is received deferred.resolve(response); }, function(error){ // Reject on error deferred.reject(error); } ); });
  112. 112. How to handle a list of deferred? require(["dojo/promise/all"], function(all){ all([promise1, promise2]).then(function(results){ // results will be an Array }); // -- or -all({ promise1: promise1, promise2: promise2 }).then(function(results){ // results will be an Object using the keys "promise1" and "promise2" }); });
  113. 113. How to create unit test in Dojo? • D.O.H.: Dojo Objective Harness • • There are several ways to run DOH tests, but the simplest way is inside a web browser. • http://localhost/dojo/util/doh/runner.html or http://localhost:8181/dojo/util/doh/runner.html
  114. 114. How to create unit test in Dojo? define(["doh/runner"], function(doh){ doh.register("MyTests", [ function assertTrueTest(){ doh.assertTrue(true); doh.assertTrue(1); doh.assertTrue(!false); }, { name: "thingerTest", setUp: function(){ this.thingerToTest = new Thinger(); this.thingerToTest.doStuffToInit(); }, runTest: function(){ doh.assertEqual("blah", this.thingerToTest.blahProp); doh.assertFalse(this.thingerToTest.falseProp); // ... }, tearDown: function(){ } }, // ... ]); });
  115. 115. What are few useful links to refer Dojo? • bugging-dojo-common-error-messages/ • nTemplateMixin • • hat-is-the-best-way-to-start-a-dojo-project/
  116. 116. References • •