Sunday, January 17, 2010

First impressions of Github

Tried out github for the first time today - bit late to the party, but better late than never.

On initial impressions, I don't immediately see the advantages of github over something like SVN/trac. Given that the tagline for Github is social coding, perhaps I'd need to be involved in a project with multiple committers to get the full github experience. Can't say that I've many complaints with svn - its a huge improvement over Rational Clearcase (which I had to use in a previous job). One definite plus of github is the ability to change code snippets through the web interface.

Regardless, http://github.com/seanoshea is where I'll be posting code snippets from now on.

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.