123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- (function($) {
- $.fn.dragsort = function(options) {
- if (options == "destroy") {
- $(this.selector).trigger("dragsort-uninit");
- return;
- }
- var opts = $.extend({}, $.fn.dragsort.defaults, options);
- var lists = [];
- var list = null, lastPos = null;
- this.each(function(i, cont) {
-
- if ($(cont).is("table") && $(cont).children().length == 1 && $(cont).children().is("tbody"))
- cont = $(cont).children().get(0);
- var newList = {
- draggedItem: null,
- placeHolderItem: null,
- pos: null,
- offset: null,
- offsetLimit: null,
- scroll: null,
- container: cont,
- init: function() {
-
- opts.tagName = opts.tagName == "" ? ($(this.container).children().length == 0 ? "li" : $(this.container).children().get(0).tagName.toLowerCase()) : opts.tagName;
- if (opts.itemSelector == "")
- opts.itemSelector = opts.tagName;
- if (opts.dragSelector == "")
- opts.dragSelector = opts.tagName;
- if (opts.placeHolderTemplate == "")
- opts.placeHolderTemplate = "<" + opts.tagName + "> </" + opts.tagName + ">";
-
- $(this.container).attr("data-listidx", i).mousedown(this.grabItem).bind("dragsort-uninit", this.uninit);
- this.styleDragHandlers(true);
- },
- uninit: function() {
- var list = lists[$(this).attr("data-listidx")];
- $(list.container).unbind("mousedown", list.grabItem).unbind("dragsort-uninit");
- list.styleDragHandlers(false);
- },
- getItems: function() {
- return $(this.container).children(opts.itemSelector);
- },
- styleDragHandlers: function(cursor) {
- this.getItems().map(function() { return $(this).is(opts.dragSelector) ? this : $(this).find(opts.dragSelector).get(); }).css("cursor", cursor ? "pointer" : "");
- },
- grabItem: function(e) {
- var list = lists[$(this).attr("data-listidx")];
- var item = $(e.target).closest("[data-listidx] > " + opts.tagName).get(0);
- var insideMoveableItem = list.getItems().filter(function() { return this == item; }).length > 0;
-
- if (e.which != 1 || $(e.target).is(opts.dragSelectorExclude) || $(e.target).closest(opts.dragSelectorExclude).length > 0 || !insideMoveableItem)
- return;
-
-
-
-
- var dragHandle = e.target;
- while (!$(dragHandle).is(opts.dragSelector)) {
- if (dragHandle == this) return;
- dragHandle = dragHandle.parentNode;
- }
- $(dragHandle).attr("data-cursor", $(dragHandle).css("cursor"));
- $(dragHandle).css("cursor", "move");
-
- var listElem = this;
- var trigger = function() {
- list.dragStart.call(listElem, e);
- $(list.container).unbind("mousemove", trigger);
- };
- $(list.container).mousemove(trigger).mouseup(function() { $(list.container).unbind("mousemove", trigger); $(dragHandle).css("cursor", $(dragHandle).attr("data-cursor")); });
- },
- dragStart: function(e) {
- if (list != null && list.draggedItem != null)
- list.dropItem();
- list = lists[$(this).attr("data-listidx")];
- list.draggedItem = $(e.target).closest("[data-listidx] > " + opts.tagName)
-
- list.draggedItem.attr("data-origpos", $(this).attr("data-listidx") + "-" + $(list.container).children().index(list.draggedItem));
-
- var mt = parseInt(list.draggedItem.css("marginTop"));
- var ml = parseInt(list.draggedItem.css("marginLeft"));
- list.offset = list.draggedItem.offset();
- list.offset.top = e.pageY - list.offset.top + (isNaN(mt) ? 0 : mt) - 1;
- list.offset.left = e.pageX - list.offset.left + (isNaN(ml) ? 0 : ml) - 1;
-
- if (!opts.dragBetween) {
- var containerHeight = $(list.container).outerHeight() == 0 ? Math.max(1, Math.round(0.5 + list.getItems().length * list.draggedItem.outerWidth() / $(list.container).outerWidth())) * list.draggedItem.outerHeight() : $(list.container).outerHeight();
- list.offsetLimit = $(list.container).offset();
- list.offsetLimit.right = list.offsetLimit.left + $(list.container).outerWidth() - list.draggedItem.outerWidth();
- list.offsetLimit.bottom = list.offsetLimit.top + containerHeight - list.draggedItem.outerHeight();
- }
-
- var h = list.draggedItem.height();
- var w = list.draggedItem.width();
- if (opts.tagName == "tr") {
- list.draggedItem.children().each(function() { $(this).width($(this).width()); });
- list.placeHolderItem = list.draggedItem.clone().attr("data-placeholder", true);
- list.draggedItem.after(list.placeHolderItem);
-
- list.placeHolderItem.children().each(function() { $(this).html(" "); });
- } else {
- list.draggedItem.after(opts.placeHolderTemplate);
- list.placeHolderItem = list.draggedItem.next().css({ height: h, width: w }).attr("data-placeholder", true);
- }
- if (opts.tagName == "td") {
- var listTable = list.draggedItem.closest("table").get(0);
- $("<table id='" + listTable.id + "' style='border-width: 0px;' class='dragSortItem " + listTable.className + "'><tr></tr></table>").appendTo("body").children().append(list.draggedItem);
- }
-
- var orig = list.draggedItem.attr("style");
- list.draggedItem.attr("data-origstyle", orig ? orig : "");
- list.draggedItem.css({ position: "absolute", opacity: 0.8, "z-index": 999, height: h, width: w });
-
- list.scroll = { moveX: 0, moveY: 0, maxX: $(document).width() - $(window).width(), maxY: $(document).height() - $(window).height() };
- list.scroll.scrollY = window.setInterval(function() {
- if (opts.scrollContainer != window) {
- $(opts.scrollContainer).scrollTop($(opts.scrollContainer).scrollTop() + list.scroll.moveY);
- return;
- }
- var t = $(opts.scrollContainer).scrollTop();
- if (list.scroll.moveY > 0 && t < list.scroll.maxY || list.scroll.moveY < 0 && t > 0) {
- $(opts.scrollContainer).scrollTop(t + list.scroll.moveY);
- list.draggedItem.css("top", list.draggedItem.offset().top + list.scroll.moveY + 1);
- }
- }, 10);
- list.scroll.scrollX = window.setInterval(function() {
- if (opts.scrollContainer != window) {
- $(opts.scrollContainer).scrollLeft($(opts.scrollContainer).scrollLeft() + list.scroll.moveX);
- return;
- }
- var l = $(opts.scrollContainer).scrollLeft();
- if (list.scroll.moveX > 0 && l < list.scroll.maxX || list.scroll.moveX < 0 && l > 0) {
- $(opts.scrollContainer).scrollLeft(l + list.scroll.moveX);
- list.draggedItem.css("left", list.draggedItem.offset().left + list.scroll.moveX + 1);
- }
- }, 10);
-
- $(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
- list.setPos(e.pageX, e.pageY);
- $(document).bind("mousemove", list.swapItems);
- $(document).bind("mouseup", list.dropItem);
- if (opts.scrollContainer != window)
- $(window).bind("wheel", list.wheel);
- },
-
- setPos: function(x, y) {
-
- var top = y - this.offset.top;
- var left = x - this.offset.left;
-
- if (!opts.dragBetween) {
- top = Math.min(this.offsetLimit.bottom, Math.max(top, this.offsetLimit.top));
- left = Math.min(this.offsetLimit.right, Math.max(left, this.offsetLimit.left));
- }
-
- var parent = this.draggedItem.offsetParent().not("body").offset();
- if (parent != null) {
- top -= parent.top;
- left -= parent.left;
- }
-
- if (opts.scrollContainer == window) {
- y -= $(window).scrollTop();
- x -= $(window).scrollLeft();
- y = Math.max(0, y - $(window).height() + 5) + Math.min(0, y - 5);
- x = Math.max(0, x - $(window).width() + 5) + Math.min(0, x - 5);
- } else {
- var cont = $(opts.scrollContainer);
- var offset = cont.offset();
- y = Math.max(0, y - cont.height() - offset.top) + Math.min(0, y - offset.top);
- x = Math.max(0, x - cont.width() - offset.left) + Math.min(0, x - offset.left);
- }
- list.scroll.moveX = x == 0 ? 0 : x * opts.scrollSpeed / Math.abs(x);
- list.scroll.moveY = y == 0 ? 0 : y * opts.scrollSpeed / Math.abs(y);
-
- this.draggedItem.css({ top: top, left: left });
- },
-
- wheel: function(e) {
- if (list && opts.scrollContainer != window) {
- var cont = $(opts.scrollContainer);
- var offset = cont.offset();
- e = e.originalEvent;
- if (e.clientX > offset.left && e.clientX < offset.left + cont.width() && e.clientY > offset.top && e.clientY < offset.top + cont.height()) {
- var deltaY = (e.deltaMode == 0 ? 1 : 10) * e.deltaY;
- cont.scrollTop(cont.scrollTop() + deltaY);
- e.preventDefault();
- }
- }
- },
-
- buildPositionTable: function() {
- var pos = [];
- this.getItems().not([list.draggedItem[0], list.placeHolderItem[0]]).each(function(i) {
- var loc = $(this).offset();
- loc.right = loc.left + $(this).outerWidth();
- loc.bottom = loc.top + $(this).outerHeight();
- loc.elm = this;
- pos[i] = loc;
- });
- this.pos = pos;
- },
- dropItem: function() {
- if (list.draggedItem == null)
- return;
-
-
- var orig = list.draggedItem.attr("data-origstyle");
- list.draggedItem.attr("style", orig);
- if (orig == "")
- list.draggedItem.removeAttr("style");
- list.draggedItem.removeAttr("data-origstyle");
- list.styleDragHandlers(true);
- list.placeHolderItem.before(list.draggedItem);
- list.placeHolderItem.remove();
- $("[data-droptarget], .dragSortItem").remove();
- window.clearInterval(list.scroll.scrollY);
- window.clearInterval(list.scroll.scrollX);
-
- if (list.draggedItem.attr("data-origpos") != $(lists).index(list) + "-" + $(list.container).children().index(list.draggedItem))
- if (opts.dragEnd.apply(list.draggedItem) == false) {
- var pos = list.draggedItem.attr("data-origpos").split('-');
- var nextItem = $(lists[pos[0]].container).children().not(list.draggedItem).eq(pos[1]);
- if (nextItem.length > 0)
- nextItem.before(list.draggedItem);
- else if (pos[1] == 0)
- $(lists[pos[0]].container).prepend(list.draggedItem);
- else
- $(lists[pos[0]].container).append(list.draggedItem);
- }
- list.draggedItem.removeAttr("data-origpos");
- list.draggedItem = null;
- $(document).unbind("mousemove", list.swapItems);
- $(document).unbind("mouseup", list.dropItem);
- if (opts.scrollContainer != window)
- $(window).unbind("wheel", list.wheel);
- return false;
- },
-
- swapItems: function(e) {
- if (list.draggedItem == null)
- return false;
-
- list.setPos(e.pageX, e.pageY);
-
- var ei = list.findPos(e.pageX, e.pageY);
- var nlist = list;
- for (var i = 0; ei == -1 && opts.dragBetween && i < lists.length; i++) {
- ei = lists[i].findPos(e.pageX, e.pageY);
- nlist = lists[i];
- }
-
- if (ei == -1)
- return false;
-
- var children = function() { return $(nlist.container).children().not(nlist.draggedItem); };
- var fixed = children().not(opts.itemSelector).each(function(i) { this.idx = children().index(this); });
-
- if (lastPos == null || lastPos.top > list.draggedItem.offset().top || lastPos.left > list.draggedItem.offset().left)
- $(nlist.pos[ei].elm).before(list.placeHolderItem);
- else
- $(nlist.pos[ei].elm).after(list.placeHolderItem);
-
- fixed.each(function() {
- var elm = children().eq(this.idx).get(0);
- if (this != elm && children().index(this) < this.idx)
- $(this).insertAfter(elm);
- else if (this != elm)
- $(this).insertBefore(elm);
- });
-
- $(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
- lastPos = list.draggedItem.offset();
- return false;
- },
-
- findPos: function(x, y) {
- for (var i = 0; i < this.pos.length; i++) {
- if (this.pos[i].left < x && this.pos[i].right > x && this.pos[i].top < y && this.pos[i].bottom > y)
- return i;
- }
- return -1;
- },
-
- createDropTargets: function() {
- if (!opts.dragBetween)
- return;
- $(lists).each(function() {
- var ph = $(this.container).find("[data-placeholder]");
- var dt = $(this.container).find("[data-droptarget]");
- if (ph.length > 0 && dt.length > 0)
- dt.remove();
- else if (ph.length == 0 && dt.length == 0) {
- if (opts.tagName == "td")
- $(opts.placeHolderTemplate).attr("data-droptarget", true).appendTo(this.container);
- else
-
- $(this.container).append(list.placeHolderItem.removeAttr("data-placeholder").clone().attr("data-droptarget", true));
- list.placeHolderItem.attr("data-placeholder", true);
- }
- });
- }
- };
- newList.init();
- lists.push(newList);
- });
- return this;
- };
- $.fn.dragsort.defaults = {
- tagName:"",
- itemSelector: "",
- dragSelector: "",
- dragSelectorExclude: "input, textarea",
- dragEnd: function() { },
- dragBetween: false,
- placeHolderTemplate: "",
- scrollContainer: window,
- scrollSpeed: 5
- };
- })(jQuery);
|