Showing posts with label dnd. Show all posts
Showing posts with label dnd. Show all posts

Saturday, January 9, 2010

Extension to dojo dnd Selector API

I've had the good fortune of using some dojo drag and drop in a recent project and have been very impressed with the flexibility offered by the APIs. The documentation and tests have been a real help for me in getting drag and drop functionality up and running quickly in my project.

After posting a quick question to the stackoverflow forums, I tried my hand at what Eugene suggested. Here's my attempt:

dojo.provide("my.ext.SelectorMixin");

dojo.require("dojo.dnd.Selector");

dojo.declare(
"my.ext.SelectorMixin",
[dojo.dnd.Selector],
{
// summary: a mixin for the dojo.dnd.Selector class which adds functionality
// to shift the currently selected index backwards and forwards. One possible
// use for this mixin would be to allow a user select different dnd items using
// the right and left keys.

shift: function(offset, shiftKey) {
// summary: shifts the currently selected dnd item
// offset: int: the amount to bump the selection by.
// shiftKey: Boolean: whether or not this new selection happened when the user was holding
// down the shift key
var selectedNodes = this.getSelectedNodes();
if(selectedNodes && selectedNodes.length) {
// only delegate to _selectNode if at least one node is selected. If multiple nodes are selected
// assume that we go with the last selected node.
this._selectNode(this._getNodeId(selectedNodes[selectedNodes.length - 1].id, offset), shiftKey);
}
},

_selectNode: function(nodeId, shiftKey) {
// summary: selects a node based on nodeId
// nodeId: String: the id of the node to select
// shiftKey: Boolean: whether or not this new selection happened when the user was holding
// down the shift key
if(!shiftKey) {
// only clear the selection if the user was not holding down the shift key
this.selectNone();
}
this._addItemClass(dojo.byId(nodeId), "Selected");
this.selection[nodeId] = 1;
},

_getNodeId: function(nodeId, offset) {
// summary: selects a node based on nodeId
// nodeId: String: the id of the node to select
// offset: int: the number of nodes to shift the current selection by
var allNodes = this.getAllNodes(), newId = nodeId;
for(var i = 0, l = allNodes.length; i < l; i++) {
var node = allNodes[i];
if(node.id == nodeId) {
// have a match ... make sure we're not at the start or the end of the dnd set
if(!((offset == -1 && i == 0) || (i == l - 1 && offset == 1))) {
// we should be fine to go with the id the user has requested.
newId = allNodes[i + offset].id;
}
break;
}
}
// if we don't get a match, the newId defaults to the currently selected node
return newId;
}
}
);


One very simple use of this extension would be to add key handlers to dojo.doc to listen for right and left keys:

dojo.connect(dojo.doc, "onkeyup", dojo.hitch(this, function(evt) {
if(evt.keyCode == dojo.keys.RIGHT_ARROW) {
this.shift(1, evt.shiftKey);
}
if(evt.keyCode == dojo.keys.LEFT_ARROW) {
this.shift(-1, evt.shiftKey);
}
}));


I'll give a shot at providing some tests for this extension in my next post.

Sunday, September 13, 2009

dojo updates

You gotta give the dojo guys credit. Thanks to @uhop for following up on my previous blog post. Even though my bug was pretty edge case, its great to see the dojo community going the extra mile to fix it. Its small things like this which make all the difference.

On another dojo related note, I attended the DDD at AOL in Mountain View on Thursday. Always good times hanging out with the dojo crew. Some really cool stuff in the pipeline too. It was great to get some samples of the dojo/django collaboration happening with Tobias and Mike's drawing samples were really cool too - I didn't know stuff like that was possible in the browser. Looking forward to dojo 1.4 already. Rob Christiansen from Adobe AIR popped in too - sounds like there's a lot in the pipeline for AIR 2.0. Maybe the dair dojo project will get rejuvenated with the arrival of AIR 2.0 and dojo 1.4

Wednesday, September 2, 2009

dojo drag and drop in AIR

Looking at common.js in the dojo.dnd package, I see this nice utility function:
Paste your text here.dojo.dnd._isMac = navigator.appVersion.indexOf("Macintosh") >= 0;
dojo.dnd._copyKey = dojo.dnd._isMac ? "metaKey" : "ctrlKey";

dojo.dnd.getCopyKeyState = function(e) {
// summary: abstracts away the difference between selection on Mac and PC,
// and returns the state of the "copy" key to be pressed.
// e: Event: mouse event
return e[dojo.dnd._copyKey]; // Boolean
};

However, this doesn't seem to work in AIR (only tested running on mac so far).

Switching the code to look like:
dojo.dnd._isMac = navigator.appVersion.indexOf("Macintosh") >= 0;
dojo.dnd._isAir = navigator.appVersion.indexOf("AdobeAIR") >= 0;
dojo.dnd._copyKey = dojo.dnd._isMac && !dojo.dnd._isAir ? "metaKey" : "ctrlKey";

seems to do the trick