Login Register

The Address Book

Andy thinks, "That was easy. Now what's the next easiest thing to do?" The left-hand side panes, Address Book and Folders, will each have a tree. The Folders tree will have a heirarchy - folders within folders - but the Address Book is nice and flat. Andy figures he'll use the Address Book to learn Dijit Trees, then use his knowledge on the more complex Folders pane later. Here's the cocktail napkin view:

mail_step2.png

Back in the old days (i.e. 5 minutes ago), Andy would have drawn up a PHP file that sent all the markup for the Address Book tree - the folder IMG tags, the labels, etc. - over the wire. While this approach worked fine in the old days, he has learned it doesn't work well for Web 2.0 applications like this one. Why?

  • It doesn't scale well. For a few entries, assembling the markup on the server, downloading, parsing and inserting the HTML is no problem. But this Address Book could contain hundreds or thousands of entries. And it will need to be drawn frequently.
  • It requires PHP to generate JavaScript. Since each Book entry needs an onlcik handler, Andy would need to embed onclick handlers into each tag. Mixing languages like this requires him to juggle syntax in his head. His mind is on other things (remember the girlfriend? the proposal?)

Address Book Data - dojo.Data and JSON

He decides to leave the architecture questions alone for a moment, and looks at the Dijit catalog entry for Tree. The easiest data-driven way to approach this uses dojo.data. Dojo.data reminds Andy of ODBC in the Windows world, JDBC in Java, and DBD in PHP (Andy gets around.) Though dojo.data can talk to many different kinds of backing stores formatted in CSV, XML or HTML, Andy picks JavaScript Object Notation, or JSON. A JSON representation of the address book would look like this:

{ 
	identifier: 'id',
	label: 'label',
	items: [
		{ type: 'address', id: 'adam', label: "Adam Arlen" },
		{ type: 'address', id: 'bob', label: "Bob Baxter" },
		{ type: 'address', id: 'carrie', label: "Carrie Crow" }
        ]
}

JSON nicely represents JavaScript objects, bracketed by { and }, and arrays bracketed by [ and ]. The attributes identifier and label conform to dojo.data's metadata specifications. Dojo.data uses the drivers dojo.data.ItemFileReadStore and dojo.data.ItemFileWriteStore to read JSON data in this format.

Andy thinks, "it'll be a snap to write a PHP for that format!" For the demo, he will simply use the above file as mail/mail.json. If the project moves past the demo phase, he can replace it with a PHP that reads mail on the database server and outputs JSON. Good deal.

To connect his demo to the data store, he inserts this below the BODY tag:

<div dojoType="dojo.data.ItemFileWriteStore" jsId="mailStore"
        url="mail/mail.json">
</div>

He has decided to use the ItemFileWriteStore to write entries back later (maybe not in the demo, but later on.)

Displaying the Address Book - Tree

Now drawing the tree is a snap using dijit.Tree:

<div dojoType="dijit.Tree" id="addrTree" store="mailStore"
        labelAttr="label" query="{type:'address'}">

        <script type="dojo/method" event="getIconClass" args="item">
                var specifiedIcon = item && mailStore.getValue(item, "icon");
                return specifiedIcon || "mailIconFolderDocuments";
        </script>
</div>

The store attribute connects to the jsId attribute on the ItemFileWriteStore. LabelAttr tells which attribute is used for the labels. Finally, the query tells dojo.data which entries to retrieve. You can equate a dojo.data query with a SQL query - it works with any backing store that dojo.data understands. As you can see here, a dojo.data query is much simpler than a SQL query. Sorting and compound selection are available for later, but for now this simple query will do fine.

Tree Icons - Extension Points

But wow ... what's up with that SCRIPT tag? What is type "dojo/method"?

That came about when Andy learned about tree icons ... the hard way. His first stab at dijit.Tree drew a nice address book but no icons. That wouldn't do. Clickdammit.com really, really likes icons. The trouble is there might be different icons based on the address book entry type.

At first Andy thought he'd have to modify dijit.Tree ... good thing Dojo is open source, right? But he'd been down that road before. You start monkeying around with changing the source and it becomes a never-ending struggle with revision control. So he read over the Dijit catalog entry for Tree and found:

mail_step2a.png

An extension point is a point at which you can add, remove or replace functionality. The Dijit designers have built lots of extension points so you can change Dijit instances to your heart's content. And that's what Andy did.

First he looked up the signature for the extension point in the API guide: dijit.Tree.getIconClass:

getIconClass: function(/*dojo.data.Item*/ item){
		// summary: user overridable function to return CSS class name to display icon
	},

Since each of the address book entries was a dojo.data.Item, he had no problem passing something in. Now he can replace the guts of the SCRIPT tag with JavaScript code to read the icon attribute and turn it into a CSS class name. That class name points to the right icon specified in mail/mail.css. Problem solved!

One note about that "item &&" phrase. In Dojo 1.0, Trees always have one and only one root node. There is nothing in dojo.data that specifies items as root nodes, and thus the first item passed to getIconClass is always null. By saying "item &&" we take advantage of JavaScript's short-circuit && (and) operator. It says "if item is a false-y value (= false, 0, null), stop here and don't evaluate what's after the &&."

"Cool!" thought Andy. Extension points made it easy to change widget behavior, and dojo/method calls did the nasty job of wiring JavaScript code.

And with a few more header entries:

dojo.require("dojo.data.ItemFileWriteStore"); 
	dojo.require("dijit.Tree");

step2.html is now a working address book. If you don't believe it, download it and try it yourself! Then we'll move right along...

AttachmentSize
icons.gif2.76 KB
step2.html3.24 KB

Not all JavaScript is valid JSON...

The snippet referred to as JSON shown above for the data store is actually JavaScript. JSON is a restricted subset of JavaScript (ie. all JSON is JavaScript, but not the inverse).

JSON constrains JavaScript syntax in a few key ways which are intended to simplify parsing and generation by languages other than JavaScript:

  • object keys must be strings
  • strings must be double-quoted
  • comments are not supported

See http://json.org/ for full explanation.

Here is a JSON valid version of the example:

{
        "identifier": "id",
        "label": "label",
        "items": [
                { "type": "address", "id": "adam", "label": "Adam Arlen" },
                { "type": "address", "id": "bob", "label": "Bob Baxter" },
                { "type": "address", "id": "carrie", "label": "Carrie Crow" }
        ]
}

fortunately,

fortunately, ItemFileReadStore realizes we both a) enjoy standards and b) are lazy by nature ;)

{ "items": { [ { "key":"value" } ] } }

works just as well as

{ item: { [ { key:"value" } ] } }

wrt to item store.

Good point Dante

It's important for a parser to be tolerant of imperfect syntax. In this case Dojo code is the consumer of the data, so it's format needs to satisfy Dojo, rather than being absolutely perfect from a JSON syntax perspective. I prefer not having to put in the quotes myself ;)

Minor typo

  • It requires PHP to generate JavaScript. Since each Book entry needs an onlcik handler, Andy would need to embed onclick handlers into each tag. Mixing languages like this requires him to juggle syntax in his head. His mind is on other things (remember the girlfriend? the proposal?)

ciao!

Yup! I remember!

The scope of this page only addresses displaying the address book for now. When I get the walkthrough completed (hopefully soon), that'll be addressed (no pun intended) in a later page.

Address book icons - steps unclear

Maybe I have missed something but it appears the details for how to show the icons in the address book is missing something. The explanation shows the script for the extension point that seems to look for an icon value [mailstore.getValue(item, "icon")] in the mail.json file - the json file shown earlier has no such attribute "icon" therefore the script defaults to look for "mailIconFolderDocuments" in the CSS file. It is not clear from the explanation whether there should in fact be some custom icons defined by means of entries in the json file.

step2.html doesn't run

I tried to click on step2.html to run it, and it didn't run. For one thing, the "item &&" instruction noted above (var specifiedIcon = item && mailStore.getValue(item, "icon");) doesn't appear in the file. I also noticed that it is trying to use this statement inside the style element, "@import "mail/mail.css";", instead of using http://o.aolcdn.com/dojo/1.0.0/dijit/demos/mail/mail.css. I think that is all I had to change to make it run. Oh, and I'm running on 1.0.2 and there is no dojo.xd.js in 1.0.2. I changed that to point to dojo/dojo.js and it worked fine.