Thursday, October 11, 2012

Migrating Dojo 1.6 to 1.7 or higher

Prerequisites : You must be familiar with Dojo 1.6 or older versions of Dojo

Whats new in Dojo 1.7?


Dojo 1.7 provides substantial improvements for building desktop and mobile apps using open web technologies. 

Here i list out few major improvements that were made to Dojo 1.7 :
  • AMD (Asynchronous Module Definition) makes use of require() and define() methods to load and define the module(s) asynchronously unlike in Dojo 1.6 which used dojo.require() and dojo.provide() to load and define the module(s) which was synchronous.
  • By default these utils were loaded in Dojo 1.6 leading to performance issue.
    • DOM Utilities like dojo.create, dojo.query etc
    • Array Utilities like dojo.isArray, dojo.forEach etc
    • Lang Utilities like dojo.hitch, dojo.partial, dojo.clone etc
    • Animation Utilities like dojo.Animation, dojo.fadeOut, dojo.fadeIn etc
  • In Dojo 1.7 developers are suppose to pull out these modules (utils) using the require()/define() method by doing so it improves the performance by loading only required modules on the client.
For configuration of Dojo 1.7 refer : http://livedocs.dojotoolkit.org/loader/amd


How to pull out the modules in Dojo 1.7 using require() and define()?


In Dojo 1.6

Example 1:
...
<script src="<%=request.getContextPath()%>/dojo/dojo/dojo.js" ></script>
<script>
dojo.require("dijit.form.ValidationTextBox"); //this was a synchronous call.
</script>
....
<div dojoType="dijit.form.ValidationTextBox" required="true" promptMessage="Enter the value"/>
...

Example 2:

dojo.require(“dijit.form.ValidationTextBox”);
dojo.provide(“custom.widget.myValidationTextBox”);
 // dojo.provide() tells the loader that the module has been provided for the given name
dojo.declare(“custom.widget.myValidationTextBox”, dijit.form.ValidationTextBox, {
            //myValidationTextBox properties
});


In Dojo 1.7

Example1 :
..
<script src="/dojo/dojo/dojo.js" data-dojo-config="parseOnLoad: true, async: true"></script> 
//Note : Here we have specified async as true which indicates we are trying to load the modules asynchronously 
<script>
require(["dijit.form.ValidationTextBox"], function(validationTextWidget){
});
</script>

//HTML 5 representation 
<div data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="required:true, promptMessage='Enter the value'"/> 
//Make sure of property types i.e. if boolean or object type is used then quotes should not be used for attribute values for example "required:'true'" is not valid.
Example2 :

define(["dojo/_base/declare","dijit/form/ValidationTextBox"], function(dojo,validationWidget){
   dojo.declare("custom.widget.myValidationTextBox", validationWidget, {
     //myValidationTextBox properties.
   }
});


Which module(s) to import and when?


I have listed out all the possible dojo methods along with its module that needs to be loaded for Dojo 1.7

Lets look at the step by step approach for migrating Dojo 1.6 to Dojo 1.7

Consider Dojo 1.6 Example:


dojo.require(“dijit.form.ValidationTextBox”);
dojo.provide(“custom.widget.myValidationTextBox”);
dojo.declare(“custom.widget.myValidationTextBox”, dijit.form.ValidationTextBox, {
           save : function(){
               var myWidget = dijit.byId('testId');
               dojo.forEach(myWidget.getDescendants(), function(childWidget){
                     dojo.destroy();
               });
           }
});


Now to migrate the above code to Dojo 1.7:

1. Identify the default loaded utils in Dojo 1.6
2. In our example its dijit.byId, dojo.forEach, dojo.destroy
3. Search for the Module(s) to Load (refer below) for appropriate util methods.
4. For dijit.byId the module to load is "dijit/registry", for dojo.forEach its "dojo/_base/array" and for dojo.destroy its "dojo/dom-construct" and these are identified as "DDijit", "DArray" and "DDomConstruct"
5. Include these module(s) in the define() function of Dojo 1.7
6. You are done with migration :)


define(["dojo/_base/declare","dijit/form/ValidationTextBox", "dijit/registry", "dojo/_base/array", "dojo/dom-construct"], function(declare,validationWidget, DDijit, DArray, DDomConstruct){
   declare("custom.widget.myValidationTextBox", validationWidget, {
         save : function(){
              var myWidget =  DDijit.byId('testId');
              DArray.forEach(myWidget.getDescendants(), function(childWidget){
                     DDomConstruct.destroy();
              });
        }
   }
});


Util Methods :


Module To Load "dojo/_base/array" Description = "Array Utilities" Identifier = "DArray"

---------------------------------------------------------------------------------------
dojo.forEach
dojo.map
dojo.some
dojo.every
dojo.filter
dojo.indexOf
***************************************************************************************

Module To Load "dojo/_base/lang" Identifier = "DLang"
 Description = "Language Utilities"
---------------------------------------------------------------------------------------
dojo.hitch
dojo.partial
dojo.clone
dojo.delegate
dojo.isString
dojo.isArray
dojo.isFunction
dojo.isObject
dojo.isArrayLike
dojo.isAlien
dojo.trim
dojo.replace
dojo.mixin
dojo.extend
dojo.getObject
dojo.setObject
dojo.exists
***************************************************************************************

Module To Load "dojo/dom" Description = "DOM Utilities"
   Identifier = "DDom"
---------------------------------------------------------------------------------------
dojo.byId
dojo.isDescendant
dojo.setSelectable
***************************************************************************************

Module To Load "dojo/dom-class" Description = "DOM Utilities"
   Identifier = "DDomClass"
---------------------------------------------------------------------------------------
dojo.hasClass
dojo.addClass
dojo.removeClass
dojo.toggleClass
dojo.replaceClass
***************************************************************************************

Module To Load "dojo/dom-attr" Description = "DOM Utilities"
 Identifier = "DDomAttr"
---------------------------------------------------------------------------------------
dojo.getAttr
dojo.isDescendant
dojo.setAttr
dojo.hasAttr
dojo.removeAttr
dojo.getNodeProp
***************************************************************************************

Module To Load "dojo/dom-construct" Description = "Dom Construct"
 Identifier = "DDomConstruct"
---------------------------------------------------------------------------------------
dojo.toDom
dojo.place
dojo.create
dojo.empty
dojo.destroy
***************************************************************************************

Module To Load "dojo/dom-style" Description = "Dojo Dom Utilities"
 Identifier = "DDomStyle"
---------------------------------------------------------------------------------------
dojo.getStyle
dojo.setStyle
dojo.getComputedStyle
dojo.toPixelValue
***************************************************************************************

Module To Load "dojo" Description = "Dojo Utilities"
 Identifier = "Dojo"
---------------------------------------------------------------------------------------
dojo.attr
dojo.position
dojo.marginBox
dojo.contentBox
dojo.coords
dojo.prop
***************************************************************************************

Module To Load "dojo/dom-prop" Description = "DomGeometry"
 Identifier = "DDomProp"
---------------------------------------------------------------------------------------
dojo.getProp
dojo.setProp
dojo.style
***************************************************************************************

Module To Load "dojo/dom-geometry" Description = "DomGeometry"
 Identifier = "DomGeometry"
---------------------------------------------------------------------------------------
dojo.getPadExtents
dojo.getBorderExtents
dojo.getPadBorderExtents
dojo.getMarginExtents
dojo.getMarginSize
dojo.getMarginBox
dojo.setMarginBox
dojo.getContentBox
dojo.setContentSize
dojo.isBodyLtr
dojo.docScroll
dojo.getIeDocumentElementOffset
dojo.fixIeBiDiScrollLeft
***************************************************************************************

Module To Load "dojo/_base/html" Description = "HTML Utilities"
 Identifier = "DHtml"
---------------------------------------------------------------------------------------

Module To Load "dojo/_base/Deferred"
 Description = "Deferred Utilities" Identifier = "DDeferred"
---------------------------------------------------------------------------------------
dojo.when
***************************************************************************************

Module To Load "dojo/_base/kernel"
 Description = "Kernel Utilities" Identifier = "DKernel"
---------------------------------------------------------------------------------------
dojo.deprecated
dojo.eval
dojo.locale
dojo.moduleUrl
dojo.version
***************************************************************************************

Module To Load "dojo/_base/window"
 Description = "Window Utilities" Identifier = "DWindow"
---------------------------------------------------------------------------------------
dojo.doc
dojo.body
dojo.setContext
dojo.withGlobal
dojo.withDoc
***************************************************************************************

Module To Load "dojo/_base/fx" Description = "Animation Utilities"
 Identifier = "DAnim"
---------------------------------------------------------------------------------------
dojo.animateProperty
dojo.Animation
dojo.anim
dojo.fadeOut
dojo.fadeIn
***************************************************************************************

Module To Load "dojo/_base/connect"
 Description = "Connection Utilities" Identifier = "DConnect"
---------------------------------------------------------------------------------------
dojo.connect
dojo.disconnect
dojo.subscribe
dojo.unsubscribe
dojo.publish
dojo.connectPublisher
***************************************************************************************

Module To Load "dojo/_base/NodeList"
 Description = "NodeList Utilities" Identifier = "DNodeList"
---------------------------------------------------------------------------------------
NodeList.events
NodeList.connect
***************************************************************************************

Module To Load "dojo/_base/unload"
 Description = "Unload Utilities" Identifier = "DUnload"
---------------------------------------------------------------------------------------
dojo.addOnUnload
dojo.addOnWindowUnload
dojo.windowUnloaded
***************************************************************************************

Module To Load "dojo/_base/xhr" Description = "Ajax Utilities"
 Identifier = "DXhr"
---------------------------------------------------------------------------------------
dojo.contentHandlers
dojo.xhrDelete
dojo.xhrGet
dojo.xhrPost
dojo.xhrPut
dojo.rawXhrPost
dojo.rawXhrPut
***************************************************************************************

Module To Load "dojo/_base/json" Description = "Json Utilities"
 Identifier = "DJson"
---------------------------------------------------------------------------------------
dojo.fromJson
dojo.toJson
***************************************************************************************

Module To Load "dojo/dom-form" Description = "Form Utilities"
 Identifier = "DForm"
---------------------------------------------------------------------------------------
dojo.fieldToObject
dojo.formToJson
dojo.formToObject
dojo.formToQuery
***************************************************************************************

Module To Load "dojo/io-query" Description = "IO QueryUtilities"
 Identifier = "DIOQuery"
---------------------------------------------------------------------------------------
dojo.objectToQuery
dojo.queryToObject
***************************************************************************************

Module To Load "dojo/ready" Description = "Dojo Utilities"
   Identifier = "DReady"
---------------------------------------------------------------------------------------
dojo.ready
***************************************************************************************

Module To Load "dojo/query" Description = "Dojo Query Utilities"
 Identifier = "DQuery"
---------------------------------------------------------------------------------------
dojo.query
***************************************************************************************

Module To Load "dojo/back" Description = "Dojo Utilities"
 Identifier = "DBack"
---------------------------------------------------------------------------------------
dojo.back
***************************************************************************************

Module To Load "dojo/data" Description = "Dojo Data Utilities"
 Identifier = "DData"
---------------------------------------------------------------------------------------
dojo.data
***************************************************************************************

Module To Load "dojo/store" Description = "Dojo Store Utilities"
 Identifier = "DStore"
---------------------------------------------------------------------------------------
dojo.store
dojo.store.Memory
dojo.store.JsonRest
dojo.store.Observable
dojo.store.Cache
***************************************************************************************

Module To Load "dojo/cache" Description = "Dojo Cache Utilities"
 Identifier = "DCache"
---------------------------------------------------------------------------------------
dojo.cache
***************************************************************************************

Module To Load "dojo/dnd" Description = "Dojo Dnd Utilities"
 Identifier = "DDnd"
---------------------------------------------------------------------------------------
dojo.dnd
***************************************************************************************

Module To Load "dojo/currency"
 Description = "Dojo Currency Utilities" Identifier = "DCurrency"
---------------------------------------------------------------------------------------
dojo.currency
***************************************************************************************

Module To Load "dojo/number" Description = "Dojo Number Utilities"
 Identifier = "DNumber"
---------------------------------------------------------------------------------------
dojo.number
***************************************************************************************

Module To Load "dojo/parser" Description = "Dojo Parser Utilities"
 Identifier = "DParser"
---------------------------------------------------------------------------------------
dojo.parser
***************************************************************************************

Module To Load "dojo/string" Description = "Dojo String Utilities"
 Identifier = "DString"
---------------------------------------------------------------------------------------
dojo.string
***************************************************************************************

Module To Load "dojo/i18n" Description = "Dojo i18n Utilities"
 Identifier = "Di18n"
---------------------------------------------------------------------------------------
dojo.i18n
***************************************************************************************

Module To Load "dojo/html" Description = "Dojo html Utilities"
 Identifier = "DHtml"
---------------------------------------------------------------------------------------
dojo.html
***************************************************************************************

Module To Load "dojo/regexp" Description = "Dojo RegEx Utilities"
 Identifier = "DRegex"
---------------------------------------------------------------------------------------
dojo.regexp
***************************************************************************************

Module To Load "dojo/cookie" Description = "Dojo Cookie Utilities"
 Identifier = "DCookie"
---------------------------------------------------------------------------------------
dojo.cookie
***************************************************************************************

Module To Load "dojo/date" Description = "Dojo Date Utilities"
 Identifier = "DDate"
---------------------------------------------------------------------------------------
dojo.date
dojo.date.locale
dojo.date.locale.addCustomFormats
dojo.date.locale.format
dojo.date.locale.getNames
dojo.date.locale.isWeekend
dojo.date.locale.parse
dojo.date.locale.regexp
***************************************************************************************

Module To Load "dijit/registry" Description = "Dijit Utils"
 Identifier = "DDijit"
---------------------------------------------------------------------------------------
dijit.byId
***************************************************************************************






2 comments:

  1. One thing I used to migrate everything to AMD was to look for "dojo." or "dijit." in my code, and get rid of all those. In your examples, you are aliasing dojo/_base/kernel to "dojo", which can lead to confusion between old and new dojo code.

    Also, I wouldn't use that syntax :

    define(["dojo/_base/kernel","dijit/form/ValidationTextBox"], function(dojo,validationWidget){
    dojo.declare("custom.widget.myValidationTextBox", validationWidget, {
    //myValidationTextBox properties.
    }
    });

    ... but rather ...

    define(["dojo/_base/declare","dijit/form/ValidationTextBox"], function(declare,validationWidget){
    return declare("custom.widget.myValidationTextBox", validationWidget, {
    //myValidationTextBox properties.
    }
    });

    This post was the most valuable to me : http://dojotoolkit.org/documentation/tutorials/1.8/modern_dojo/

    ReplyDelete