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!!

Writing a simple, self contained tab container Dijit in Dojo

Over the last few weeks, I’ve been working with a new team and have been putting together some versatile dijits that are to be used throughout the UI. Today I spent some time working on an idea for a tab container which requires little or no customisation / interaction to get set up and running.

Additional Comment: The reason why I have done this over using the built in Dojo TabContainer is that I find it to be a bit ‘over the top’ for simple use as a plain tab container. I get faced with steep design guidelines by clients and even STEEPER browser requirements (such asIE6) and as a result, I find that it’s important to keep the memory / processor useage to a minimum and ensure that the fewest number of dom nodes are created. Thus, my ‘lite’ tabContainer was born!

I’ve spent the last hour or two re-writing a clean room version which I’d like to show to you all to demonstrate how easy it is to style and manipulate dom elements once you have them on the page.

Click to skip to the Demo Page

The idea was simple…
Get a tab container on a page, with tab switching, tab change events and a way to set which tab is shown externally.
The main requirement I gave myself what that it MUST be simple and self contained. In the past I’ve added tabs and panes to the page separately and then connected their events, but this proves fiddly and repetitive, so I’ve worked all of the variables into the dijit attributes, settable via it’s declarative marking! So…

What’s in the template…
…Not much

<div class="tabContainer">
	<ul dojoAttachPoint="_listNode"></ul>
	<div dojoAttachPoint="containerNode" class="content"></div>
</div>

An outer div with a class to restrict my CSS calls easily, a list to hold the tabs and a ‘content’ div with the magic attach point ‘containerNode’. As mentioned before, this is used throughout the dijit framework, and is where the innerHTML of your dijit declaration is copied to when the dijit is parsed. So this is the div into which our tab pane content will be put.

Now for the declaration…

<div dojoType="tom.dijit.TabContainer">
	<div tab="tab1" label="Tab One" selected="true">Content One</div>
	<div tab="tab2" label="Tab Two">Content Two</div>
	<div tab="tab3" label="Tab Three">Content Three</div>
</div>

As you can see, I’m putting using the ‘tab’ and ‘label’ attrs of the inner divs to define my parameters. The ‘tab’ param is the name that the tabContainer dijit will refer to the pane by, these need to be unique within each tabContainer level. The ‘label’ param is simply picked up and placed as the link text inside the tab and is the text that the user will see. And that’s all there is to it from a html point of view. This simple model allows n layer nesting of tab containers and makes it all very simple.

So how does that work…
Well, during the post create of the tabContainer dijit, I run a dojo query for all immediate children on my containerNode with the attribute ‘tab’. For each of these, I get hold of it’s tab and label attributes and create a list item and link for each result in the list node. I then add this info along with attach points to both the pane node and the tab node to a dijit level object and finally, I check to see if the pane has ‘selected==true’ and apply the selected class to it’s tab accordingly. If a pane is not ‘selected’, I hide it using a simple ‘display:none’ class named hidden.

postCreate : function() {
		this.inherited(arguments);
		
		//look for divs with a tab attr inside my container node!
		dojo.query("> div[tab]", this.containerNode).forEach(dojo.hitch(this, function(thisNode){
			//start building up our tab object
			var tabObj = {	"paneNode" : thisNode,
							"label" : dojo.attr(thisNode, "label") ? dojo.attr(thisNode, "label") : "Undefined" };
			//get the tab name, we'll need this!
			var tabName = dojo.attr(thisNode, "tab");
			
			//add a list item and an anchor tag to the list
			var tabItem = dojo.create("li", {"class":"tab"}, this._listNode);
			var tabLink = dojo.create("a", {"innerHTML": tabObj.label, "href":"javascript:;", "tab":tabName}, tabItem);
			tabObj.tabNode = tabItem;
			
			//connect the onclick event of our new link
			dojo.connect(tabLink, "onclick", this, "_onTabLinkClick");
			
			//now add our tabObj to the dijit level tabList so we can 
			//get to it later
			this._tabList[tabName] = tabObj;
			
			//get hold of the selected attr, to see if it should
			//be initially visible - last one found will win this battle
			var selected = dojo.attr(thisNode, "selected");
			
			if (!selected) {
				//not selected, so adding hidden class
				//(hidden class defined in global css as display:none)
				dojo.addClass(thisNode, "hidden");
			}
			else {
				//this ones selected, so put the name into our selectedTab var
				this._selectedTab = tabName;
				//add a 'selected' class to our tab list item
				dojo.addClass(tabItem, "selected");
			}
		}));		
	}

The result of all of this, is a very plain dom tree with all the elements we need to flesh out via CSS a lightweight, customisable tabContainer.

For the purposes of this demo, I have added a bounding border and a wrapper div to show the tabContainer’s containment.

So with a little bit of CSS effort, you can now transform this shell to any number of tabContainer layouts. For now, here’s a screenshot and a snippet of a small bit of CSS to give you a feel (bare in mind I spent 2 min on this CSS).
I hope to add another post in a few days to go over how to style the dijit and use the tabContainer’s events and functions to interact with a page controller (page level javascript).

Once again, I’ve used dashed borders to show where boundaries lie. The basic CSS is shown below

div.tabContainer > ul {
	list-style: none;
	padding: 0;
	margin: 0;
	height: 25px;
}

div.tabContainer > ul > li {
	float: left;
	height: 15px;
	padding: 5px;
	margin: 0px 5px;
	background: black;
}

div.tabContainer > ul > li > a {
	text-decoration: none;
	color: #EBEBED;
}

div.tabContainer > ul > li:hover,
div.tabContainer > ul > li:hover a {
	background: #EBEBED;
	color: #black;
}

div.tabContainer > ul > li.selected a {
	color: #729fcf;
	font-weight: bold;
}

Click the link to go take a look at a working demo (which I’ll upload shortly after completing this post!)
TabContainer Demo Page

TabContainer Full JS Source Code

Enjoy!

Styling dijit.form.Button, the easy way!… with baseClass

As a follow up to my previous post, I’d like to add to my final comment about using the baseClass attr on dijit.form.Button to make styling nice and easy!

In the past, when trying to use the class attr to skin a dojo button, I’ve always came across problems, because they class you add ends up about 4 layers deep into the Dijit, thus making it hard to get a handle to the outer elements of it.
To get around this, I’ve adopted a method of ‘wrapping’ a button in a span with an appropriate class as follows:

<span class="roundBlueButton">
	<div dojoType="dijit.form.Button">Text</div>
</span>

Allowing CSS as follows:

span.roundBlueButton .dijitButton {
	//now let's style it!!
}

BUT, obviously that’s not ideal now is it?!
So digging around inside some dijit button demos, (search for Test_Button.html in the dijit code base) I found an example where the class “acmeButton” is added to some buttons, not using ‘class’, but by using the mythical ‘baseClass’ attribute. It seems that this attribute overrides the class on the outermost element of a dijit.form.Button and allows you to now, finally, get a handle on that button and unleash your creative side!

<div dojoType="dijit.form.Button" baseClass="tomButton">Text</div>
.tomButton {
	//now let's style it!!
}

Even better still, this seems to remove the dijitButton class rather than adding to it, meaning that your dijit Button, is now a nice, plain black bordered, white backgrounded button…basically a blank canvas!!

This custom class you have added, now get’s used in the button’s CSS mix in functions. So in the case of my tomButton class, you’ll find that your dijit gets supplemented with tomButtonHover, tomButtonActive and tomButtonFocused under the right circumstances. Thus allowing you to style hover over effects etc.. for troublesome browsers such as IE6, IE7, IE8, probably IE9 and then IE10, 11, 12 etc.. going forward!

So there you have it! An easy way to style a dijit Button! This ‘baseClass‘ attribute should be applicable to many different types of button!
So good luck and enjoy!!

As a final comment: I’ve found that in some cases you need to add ‘!important‘ tags to your CSS classes in order to ensure that they get applied. This seems to be required when trying to apply background images etc…

Some IE6 ‘niggles’….

Been working with IE6 recently, (yes, the browser even MS has shunned) and have amazingly come across some issues!

I thought I would share some of them with anyone who cares to read this blog, as you may well come across them too!

Concatenated classes in CSS selectors? No Thankyou says IE6!

Spent a while the other day trying to prove that it’s “really easy” to skin dojo dijits for use on a clients system recently, and wrote some efficient CSS to enable the application of different classes for size, colour and type etc… Trouble is, I couldn’t get the bloody thing to work! Tried everything, but alas, hit the IE6 CSS selector brick wall.  Turns out, that IE6 only sees the last class you apply! So something like the following:

.dijitButton.Big.Red {
	//make this button big and red
}

.dijitButton.Small.Red {
	//make this button small and red
}

Kept making all of my “Red” buttons go small, no matter what code I put in the first CSS section. Now this may not seem like a big problem in this case, but take a look at the following:

.dijitButton.Big.Red {
	background: red;
}

.dijitTextBox.Red {
	color: red;
}

In this case, when you apply this CSS to your IE6 page, it cannot tell the different between the two selectors. All it sees is the class “Red” and will match both rules to anything with this class. The result, a useless dijitTextBox with a red background AND a red foreground!
The way around this seems to be to use large, unruly, nasty, horrible, unmaintainable, slow, inefficient combined classes… ie.

//when mouse out
<div class="outerDivBlue">
	<span class="innerSpanLarge"></span>
</div>

//when mouse over (after some JS)
<div class="outerDivBlueHover">
	<span class="innerSpanLarge"></span>
</div>

Thus meaning that you CSS needs to cover every base when defining selectors. ie.

div.outerDivBlue span.innerSpanLarge,
//shouldn't need this second line!!!
div.outerDivBlueHover span.innerSpanLarge {
	float: left;
	background: blue;
	min-width: 200px;
}

Anyway.. hopefully you can see my point! Luckily, it turns out that some dijits like dijit.form.Button allow you to override the baseClass, thus giving you this class concatenation for free.

<div dojoType="dijit.form.Button" baseClass="tomButton">Text</div>

<!-- Now I have access to exciting classes such as:
	tomButtonHover, tomButtonActive and tomButtonFocused -->

So someone’s done the hard work for us! Oh, and if you’re wondering why I didn’t just use Pseudo Classes like :hover etc.. I laugh in your general direction…IE6 knows not of such useful ‘Pseudo classes’…Oh, and final thought… IE6 seems to prefer CSS ordering to selection specificity, brilliant…!

So Thank-you MS..you are a winner!

Custom Dijit Best Practises (Part 2)

Welcome to part two of my dijit best practises post! If you missed part one, please take a look at Part One

Use set and get functionality for dijits

Dijit has a built in mechanism for setting and getting values on a dijit. If you take a look at the dijit codebase, you will see functions like _setTitleAttr() and _getValueAttr() across the board. These are used as setters and getters for the dijit and enable you to perform a custom function before setting a class value on your dijit. For instance, if you want to pass in a title value to your function, and you want to set this value on a domnode as well as set the class value, you can write a function as follows

_setTitleAttr : function(pTitle) {
	//set the class variable
	this.title = pTitle;
	//now set innerHTML on the title span
	dojo.attr(this.titleSpan, "innerHTML", this.title);
}

This works because when you call myDijit.set(“title”, “My Title Value”); on your dijit, the framework takes the first param (in this case “title”) and looks for a function named “_setTitleAttr” on your dijit. If this is found, the second param to the function call is passed in, if it is not found, then the framework will setup a class variable with the same name on the dijit. Using it in the latter way when you do not wish to perform any extended function is advised over simply calling myDijit.title = “My Title” as it helps to ensure cross browser compatability.
The same action is performed when you call myDijit.get(“title”). In this case, you may not wish to write a custom function, as simply returning this.title is probably adequate, but this get pattern is useful if the values you require are dynamic or domNode based. Ie. If your dijit contained check boxes and you wanted a function to return all of those that are checked.


_getCheckedAttr : function() {
	//setup return var
	var checkedOptions = [];
	//query for boxes in dijit
	dojo.query("div.dijitCheckBox", this.containerNode).forEach(function(node){
		var checkDijit = dijit.byNode(node);
		if (checkDijit) {
			if (checkDijit.get("checked") === true) {
				//checked, so add value to the return array
				checkedOptions.push(checkDijit.get("value"));
			}
		}
	});
	return checkedOptions;
}

Utilise the dijit lifecycle, but don’t forget to inherit from dijit class

Dojo has a built in dijit framework from contruction through to destruction. When writing your own dijits it’s good practice to start each .js file with a skeleton class which hits each phase of the lifecycle.
When following this practice, it’s important to remember to invoke the standard dijit methods. You can do this by calling this.inherited(arguments) in each overridden function. In most cases this should be done as the first line of each function, this ensures that the lifecycle has completed before you add new functionality.

Please note, that it is not necessary to override all of the lifecycle events in your widget, you can pick and chose which ones you would like to extend.  When not overriding these functions, the Dojo lifecycle will complete as usual, so there in no need to enter blank functions purely containing this.inherited(arguments) into your code.  The ones that I find myself using most are probably constructor, buildRendering and postCreate.

	constructor: function (){
		//Do not use this.inherited here
		//it is handled by the dojo inheritance
		//mechanism
	},

	postMixInProperties: function () {
		this.inherited(arguments);
	},

	buildRendering: function () {
		this.inherited(arguments);
	},

	postCreate: function () {
		this.inherited(arguments);
	},

	startup: function () {
		this.inherited(arguments);
	},

	destroy: function () {
		this.inherited(arguments);
	}

For more info on the lifecycle, take a look at the dijit documentation http://dojotoolkit.org/reference-guide/dijit/_Widget.html and here http://dojotoolkit.org/reference-guide/quickstart/writingWidgets.html (thanks to Ken for the second link)

Custom Dijit Best Practises (Part 1)

(WORK IN PROGRESS)
Dojo is a powerful toolkit, use it like one
First and foremost, Dojo is a powerful toolkit and should be used as such.  It provides a wealth of functions and attributes you can use within your templates and allows you to extend it’s dijit framework to create your own dijits.

When writing your own custom Dijits and extending dijit._Widget and dijit._Templated there are certain best practices to follow in order to ensure that your dijits play nicely with the rest of the dojo dijits and are easily maintainable in the future.  Here are a few of the ‘Best Practises’ I have found useful when writing my own:

Adding ‘containerNode’ dojoAttachPoint to the outer div of a template

When creating a custom Dijit, you should add a containerNode attach point to the outer Div of the template.  This enables you to address the outer div of the dijit with this.containerNode.  Furthermore, it follows the pattern used throughout the dijit framework which helps to ensure that any inherited functions will work correctly.

<div dojoAttachPoint=”containerNode”>
	<img src=”../images/icon.png”/>
	<div dojoType=”dijit.form.Button”></div>
</div>

Use dojoAttachEvent for attaching events in widgets

This may sound obvious, but more often than not, I’ve reviewed code and found that dojo.connect is being used during runtime to attach an event to a domnode, when this work could have been done by the dojo parser using the dojoAttachEvent attribute.

The format for this is dojoAttachEvent=”<eventName>:<eventToBeFired>”

<div dojoAttachPoint=”containerNode”>
	<img src=”../images/icon.png”/>
	<div dojoType=”dijit.form.Button” dojoAttachEvent="onClick:_onMyButtonClick"></div>
</div>

In your accompanying javascript file, you need to create an appropriate function named _onMyButtonClick otherwise the dijit will fail to load.

_onMyButtonClick : function(evt) {
	//do something with the event
}

Please read on to Part Two