How to make your generated widget’s DOM IDs reflect their AMD module

In the new AMD world, it’s suggested that we omit the specification of a “declaredClass” in our custom widget’s declare() call, like so:

define(["dijit/_WidgetBase"], function(_WidgetBase) {
    return declare([_WidgetBase], { 

    })
});

However, in this case, _WidgetBase doesn’t have a specified value for declaredClass, and uses the declaredClass from an appropriate parent class to automatically generate a DOM ID.

I’ve worked around this so far by using a pattern like this:

define(["module", "dijit/_WidgetBase"], function(module, _WidgetBase) {
    return declare(module.id, [_WidgetBase], { 

    })
});

Hopefully we’ll see some fixes from Dojo here to make this easier in future.

Loading page specific AMD code by body id

So I have been writing a website recently for a local primary school. Naturally Dojo was the way forward.

I had a few server side problems to solve as it is to be running on a pretty basic RM school server, so I decided to host the “CMS” in a google spreadsheet. (subject for a later post).
Anyway, long story short, each page of the website need to pull down its appropriate data from the spreadsheet and render this on the page. This code could easily have been put into the page head of each page or split into separate JS files, but I thought, NO, I’ve seen jquery code (in my distant travels to dark lands) that uses the Id tag of the page body to pull code in from an array, maybe I’ll take that approach.
Seemed to make sense and have some pros

  • only need to load the JS once
  • caching of the JS file (unlikely to change much)
  • shared code
  • simple to edit, blocks of code in a single file

So, I set About moving all of my individual page code into a single file, this file held an object, with the appropriate page Id take used as an array reference to its initialisation function.

inits = {
    homePage : function() { },
    eventsPage : function() { },
   ...etc...
}

Problem I found, was that each of my functions was pre firing as soon as he code was read in, and why I hear you ask, because they weren’t just functions, they were calls out to require.js using the Dojo AMD format. So naturally they were self firing… which caused problems. Ie.

define([],function(){
   return {
      homePage : require(["dojo/dom", "dojo/ready"], function(dom, ready) { },
   ...etc...
   }
});

So, thinking hat back on. Decided to split each of my init functions up into separate array of requires and callback function. Simple enough idea, but effective. Ie.

define([],function(){
	return {
		homePage : {	"requires": ["dojo/io/script", "dojo/_base/array"],
						"callback" : function(ioScript, arrayUtil) {
							//Do stuff
						}
					},

		eventsPage : {	"requires" : ["dojo/dom-construct", "dojo/json"],
						"callback" : function(domConstruct, json) {
							//Do stuff						
						}
					}
	}
});

So now it plays nice!
each page now pulls in a single init.js script that pulls in a ‘run everytime’ requires / callback combo to set up side wide alerts, and then gathers the id of the body tag, and pulls in the appropriate requires / callback combo and runs it.

require(["dojo/ready", "um/inits"], function(ready, initFuncs){
	ready(function(){
		
		require(initFuncs.globalAlert.requires, initFuncs.globalAlert.callback);

		//call global alert setup
		var bodyId = window.document.body.id;
		if (bodyId && initFuncs[bodyId]) {
			require(initFuncs[bodyId].requires, initFuncs[bodyId].callback);
		}

	});
});

Thought it was a nice and simple single page, multi initialisation function AMD loaded approach.
Would appreciate feedback ladies and gentlemen.

Full google spreadsheet explanation in a later post!!