The problem is our tree does nothing but stand around looking beautiful. Nothing wrong with that. Normally, though, you'd want some kind of actions.
At the very least, you probably want to do something when a user clicks or press [ENTER] on a node. To do this, you can use the onClick event.
Alternatively, you can use Dojo's publish/subscribe event system. When a node is clicked, the tree id is sent as the topic along with the message:
Dojo trees are great, and so is Dojo Drag And Drop (DnD). But together, they're unstoppable! Not being satisfied with our selection of Pop Tarts, we'll create a pool of Drag and Drop sources to add:
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #b1b100;} .geshifilter .kw2 {color: #000000; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #cc66cc;} .geshifilter .sc0 {color: #00bbdd;} .geshifilter .sc1 {color: #ddbb00;} .geshifilter .sc2 {color: #009900;}The user should only be allowed to drop a Pop Tart on its home category - for example, Blueberry should only go under Fruit. To handle this, we use JavaScript regular expressions to make an intelligent guess. We add these to the data store:
{ label: 'name',
identifier: 'name',
items: [
{ name:'Fruit', type:'category', regexp:'.*erry$'},
{ name:'Cinammon', type: 'category', regexp:'[Cc]innamon',
children: [
{ name:'Cinammon Roll', type:'poptart' },
{ name:'Brown Sugar Cinnamon', type:'poptart' },
{ name:'French Toast', type:'poptart' }
]
},
{ name:'Chocolate', type: 'category', regexp:'([Cc]hocolate|Fudge)'}
]
}
You can download this file below. Next we wire in DnD to the Tree. This is as simple as specifying two attributes: the controller and the acceptance checker extension point, which we'll write shortly.
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #b1b100;} .geshifilter .kw2 {color: #000000; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #cc66cc;} .geshifilter .sc0 {color: #00bbdd;} .geshifilter .sc1 {color: #ddbb00;} .geshifilter .sc2 {color: #009900;}The checkItemAcceptance extension point function is called each time a drop target is entered. In Tree's case, every node is a drop target. How do we know it's valid? The function must check the dragged node to the regular expression of the drop node:
function poptartCheckItemAcceptance(node,source) {
// Get the associated dojo.data item for the target
item = dijit.getEnclosingWidget(node).item;
// Need to check for item because when dropping on a root node,
// item === null
if (! item) return false;
ptType = ptTree.store.getValue(item,"type");
if (ptType == 'category') {
// We make intelligent guesses about the correct folder
re = new RegExp(ptTree.store.getValue(item,"regexp"));
okToMove = true;
for (var itemId in source.selection) {
console.debug(itemId+" tested against "+re.toString());
okToMove &= re.test(itemId);
}
return okToMove;
}
else
return false;
}
So now all the pieces are in place, yielding:
And here's the full source code, which is downloadable below:
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #b1b100;} .geshifilter .kw2 {color: #000000; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #cc66cc;} .geshifilter .sc0 {color: #00bbdd;} .geshifilter .sc1 {color: #ddbb00;} .geshifilter .sc2 {color: #009900;}