Login Register

Trees and Dojo.Data

To desconstruct the previous example, we need some dojo.data terminology:

  • an attribute is a named data set, much like a field or a column of a database,
  • A value is the data itself. So in "name: 'Fruit'", name is the attribute, Fruit is the value.
  • an item is one set of related attributes, much like a record or row. Unlike pure relational tables, items can have items nested within.
  • an identifieris an attribute that uniquely identifies the item, like a primary key

dijit.Tree, conforming to the dojo.data spec, expects the following in its data store:

  • The store attribute must be the name of a dojo.data data store.
  • Each item in the data store must have a label (as returned by getLabel())
  • An identifier attribute must be specified, even though it's not displayed.

So now let's take a step further. There are two methods to nesting a tree, corresponding to the two heirarchical methods in dojo.data.

Heirarchical Data

The easiest method for fixed text is to nest the items in the data store. To add a subtree, you must add a children attribute to the parent item, then add the child items to the children attribute. So for our previous example, we can add nodes under the Cinammon node:

Method 1: Direct Nesting

{ label: 'name',
  identifier: 'name',
   items: [
     { name:'Fruit', type:'category'},
     { name:'Cinammon', type: 'category',
       children: [
          { name:'Cinammon Roll', type:'poptart' },
          { name:'Brown Sugar Cinnamon', type:'poptart' },
          { name:'French Toast', type:'poptart' }
       ]
     },
     { name:'Chocolate', type: 'category'}
  ]
}

By downloading this file into poptarts.txt, you can use the same HTML as our previous example. And voila!

Method 2: References

Direct Nesting is a little inconvenient for relational table data. So Tree supports references, where all the data nodes are at the same level, but nesting occurs with psuedo pointers to child nodes. So our example above is written:

{ label: 'name',
  identifier: 'name',
   items: [
     { name:'Fruit', type:'category'},
     { name:'Cinammon', type: 'category',
        children: [
           {_reference: 'Cinammon Roll'},
           {_reference:'Brown Sugar Cinnamon'},
           {_reference:'French Toast'}
        ]
     },
     { name:'Cinammon Roll', type:'poptart' },
     { name:'Brown Sugar Cinnamon', type:'poptart' },
     { name:'French Toast', type:'poptart' },
     { name:'Chocolate', type: 'category'}
    ]
}

Like our nested children example, the parent node requires a children attribute. But instead of actual items, you place reference objects linking to the identifier of another object. This requires a small change to the Tree tag:

<div dojoType="dijit.Tree" store="popStore2"
     labelAttr="name" label="Pop Tarts"
     query="{type:'category'}">
</div>

The query is necessary to choose only the top level items from the store. The menu produced is exactly the same:

Icon Classes

AttachmentSize
poptarts_direct.txt380 bytes
poptarts_ref.txt499 bytes

/* GeSHi (C) 2004 - 2007

<script type="text/javascript" charset="utf-8">
    
    var data = {data: {  label: 'name',
    		identifier: 'name',
    		items: [
    			{ name:'Fruit', type:'category'},
    			{ name:'Cinammon', type: 'category'},
    			{ name:'Chocolate', type: 'category'}
    		]
    	}};
    
    var fruitStore=new dojo.data.ItemFileReadStore(data);
        
  </script>

	<div dojoType="dijit.Tree" id="mytree" store="fruitStore" label="Fruits"></div>

It's worth adding this here, note the format of the inline JSON for the store, this was the simplest example I could come up with that created a tree without needing an external file.

identifier changed to id in 1.0

The format:

{ label: 'name',
identifier: 'name',
items: [

will not work in version 1.0. "identifier" was changed to "id". Widget's parsing of JSON results seem to fail silently if you don't use "id"