// TODO: refactor away duplicationg in DragSort and DragSortX var BetterDragSort = { makeListSortable : function(list) { var items = list.getElementsByTagName("li"); for (var i = 0; i < items.length; i++) { BetterDragSort.makeItemSortable(items[i]); } }, makeItemSortable : function(item) { Drag.makeDraggable(item); item.setDragThresholdY(5); item.onDragStart = BetterDragSort.onDragStart; item.onDrag = BetterDragSort.onDrag; item.onDragEnd = BetterDragSort.onDragEnd; }, onDragStart : function(nwPosition, sePosition, nwOffset, seOffset) { var items = this.parentNode.getElementsByTagName("li"); var minOffset = Coordinates.northwestOffset(items[0], true); var maxOffset = minOffset; for (var i = 0; i < items.length; i++) { maxOffset = maxOffset.max(Coordinates.northwestOffset(items[i], true)); } this.constrain(minOffset, maxOffset); }, onDrag : function(nwPosition, sePosition, nwOffset, seOffset) { var swapper = null; var next = DragUtils.nextItem(this); while (next != null) { var nextNWOffset = Coordinates.northwestOffset(next, true); var nextSEOffset = Coordinates.southeastOffset(next, true); if (nwOffset.y >= (nextNWOffset.y - 2) && nwOffset.y <= (nextSEOffset.y + 2) && nwOffset.x >= (nextNWOffset.x - 2) && nwOffset.x <= (nextSEOffset.x + 2)) { var swapper = next; break; } var next = DragUtils.nextItem(next); } if (swapper != null) { BetterDragSort.moveAfter(this, swapper); return; } var previous = DragUtils.previousItem(this); while (previous != null) { var previousNWOffset = Coordinates.northwestOffset(previous, true); var previousSEOffset = Coordinates.southeastOffset(previous, true); var fudgeFactor = 2; if (nwOffset.y >= (previousNWOffset.y - fudgeFactor) && nwOffset.y <= (previousSEOffset.y + fudgeFactor) && nwOffset.x >= (previousNWOffset.x - fudgeFactor) && nwOffset.x <= (previousSEOffset.x + fudgeFactor)) { var swapper = previous; break; } var previous = DragUtils.previousItem(previous); } if (swapper != null) { BetterDragSort.moveBefore(this, swapper); return; } }, moveAfter : function(item1, item2) { var parent = item1.parentNode; parent.removeChild(item1); parent.insertBefore(item1, item2.nextSibling); item1.style["top"] = "0px"; item1.style["left"] = "0px"; }, moveBefore : function(item1, item2) { var parent = item1.parentNode; parent.removeChild(item1); parent.insertBefore(item1, item2); item1.style["top"] = "0px"; item1.style["left"] = "0px"; }, onDragEnd : function(nwPosition, sePosition, nwOffset, seOffset) { this.style["top"] = "0px"; this.style["left"] = "0px"; } }; var DragSort = { makeListSortable : function(list) { var items = list.getElementsByTagName("li"); for (var i = 0; i < items.length; i++) { DragSort.makeItemSortable(items[i]); } }, makeItemSortable : function(item) { Drag.makeDraggable(item); item.setDragThresholdY(5); item.onDragStart = DragSort.onDragStart; item.onDrag = DragSort.onDrag; item.onDragEnd = DragSort.onDragEnd; }, onDragStart : function(nwPosition, sePosition, nwOffset, seOffset) { var items = this.parentNode.getElementsByTagName("li"); var minOffset = Coordinates.northwestOffset(items[0], true); var maxOffset = Coordinates.northwestOffset(items[items.length - 1], true); this.constrain(minOffset, maxOffset); }, onDrag : function(nwPosition, sePosition, nwOffset, seOffset) { var parent = this.parentNode; var item = this; var next = DragUtils.nextItem(item); while (next != null && this.offsetTop >= next.offsetTop - 2) { var item = next; var next = DragUtils.nextItem(item); } if (this != item) { DragUtils.swap(this, next); return; } var item = this; var previous = DragUtils.previousItem(item); while (previous != null && this.offsetTop <= previous.offsetTop + 2) { var item = previous; var previous = DragUtils.previousItem(item); } if (this != item) { DragUtils.swap(this, item); return; } }, onDragEnd : function(nwPosition, sePosition, nwOffset, seOffset) { this.style["top"] = "0px"; this.style["left"] = "0px"; } }; var DragSortX = { makeListSortable : function(list) { var items = list.getElementsByTagName("li"); var minOffset = Coordinates.northwestOffset(items[0], true); var maxOffset = Coordinates.northwestOffset(items[items.length - 1], true); for (var i = 0; i < items.length; i++) { Drag.makeDraggable(items[i]); items[i].constrain(minOffset, maxOffset); items[i].setDragThresholdX(5); items[i].onDrag = DragSortX.onDrag; items[i].onDragEnd = function(nwPosition, sePosition, nwOffset, seOffset) { this.style["top"] = "0px"; this.style["left"] = "0px"; }; } }, onDrag : function(nwPosition, sePosition, nwOffset, seOffset) { var parent = this.parentNode; var item = this; var next = DragUtils.nextItem(item); while (next != null && this.offsetLeft >= next.offsetLeft - 2) { var item = next; var next = DragUtils.nextItem(item); } if (this != item) { DragUtils.swap(this, next); return; } var item = this; var previous = DragUtils.previousItem(item); while (previous != null && this.offsetLeft <= previous.offsetLeft + 2) { var item = previous; var previous = DragUtils.previousItem(item); } if (this != item) { DragUtils.swap(this, item); return; } } }; var DragUtils = { swap : function(item1, item2) { var parent = item1.parentNode; parent.removeChild(item1); parent.insertBefore(item1, item2); item1.style["top"] = "0px"; item1.style["left"] = "0px"; }, nextItem : function(item) { var sibling = item.nextSibling; while (sibling != null) { if (sibling.nodeName == item.nodeName) return sibling; sibling = sibling.nextSibling; } return null; }, previousItem : function(item) { var sibling = item.previousSibling; while (sibling != null) { if (sibling.nodeName == item.nodeName) return sibling; sibling = sibling.previousSibling; } return null; } };