PageSourceSearch

https://www.invitop.com/assets/js/kaka/libs/dragsort/jquery.dragsort-0.5.2.js

js invitop.com collected 2026-10-08 11:27:30 UTC 16,164 bytes, 381 lines download raw bytes

1// jQuery List DragSort v0.5.2
2// Website: http://dragsort.codeplex.com/
3// License: http://dragsort.codeplex.com/license
4
5(function($) {
6
7	$.fn.dragsort = function(options) {
8		if (options == "destroy") {
9			$(this.selector).trigger("dragsort-uninit");
10			return;
11		}
12
13		var opts = $.extend({}, $.fn.dragsort.defaults, options);
14		var lists = [];
15		var list = null, lastPos = null;
16
17		this.each(function(i, cont) {
18
19			//if list container is table, the browser automatically wraps rows in tbody if not specified so change list container to tbody so that children returns rows as user expected
20			if ($(cont).is("table") && $(cont).children().length == 1 && $(cont).children().is("tbody"))
21				cont = $(cont).children().get(0);
22
23			var newList = {
24				draggedItem: null,
25				placeHolderItem: null,
26				pos: null,
27				offset: null,
28				offsetLimit: null,
29				scroll: null,
30				container: cont,
31
32				init: function() {
33					//set options to default values if not set
34					opts.tagName = opts.tagName == "" ? ($(this.container).children().length == 0 ? "li" : $(this.container).children().get(0).tagName.toLowerCase()) : opts.tagName;
35					if (opts.itemSelector == "")
36						opts.itemSelector = opts.tagName;
37					if (opts.dragSelector == "")
38						opts.dragSelector = opts.tagName;
39					if (opts.placeHolderTemplate == "")
40						opts.placeHolderTemplate = "<" + opts.tagName + ">&nbsp;</" + opts.tagName + ">";
41
42					//listidx allows reference back to correct list variable instance
43					$(this.container).attr("data-listidx", i).mousedown(this.grabItem).bind("dragsort-uninit", this.uninit);
44					this.styleDragHandlers(true);
45				},
46
47				uninit: function() {
48					var list = lists[$(this).attr("data-listidx")];
49					$(list.container).unbind("mousedown", list.grabItem).unbind("dragsort-uninit");
50					list.styleDragHandlers(false);
51				},
52
53				getItems: function() {
54					return $(this.container).children(opts.itemSelector);
55				},
56
57				styleDragHandlers: function(cursor) {
58					this.getItems().map(function() { return $(this).is(opts.dragSelector) ? this : $(this).find(opts.dragSelector).get(); }).css("cursor", cursor ? "pointer" : "");
59				},
60
61				grabItem: function(e) {
62					var list = lists[$(this).attr("data-listidx")];
63					var item = $(e.target).closest("[data-listidx] > " + opts.tagName).get(0);
64					var insideMoveableItem = list.getItems().filter(function() { return this == item; }).length > 0;
65
66					//if not left click or if clicked on excluded element (e.g. text box) or not a moveable list item return
67					if (e.which != 1 || $(e.target).is(opts.dragSelectorExclude) || $(e.target).closest(opts.dragSelectorExclude).length > 0 || !insideMoveableItem)
68						return;
69
70					//prevents selection, stops issue on Fx where dragging hyperlink doesn't work and on IE where it triggers mousemove even though mouse hasn't moved,
71					//does also stop being able to click text boxes hence dragging on text boxes by default is disabled in dragSelectorExclude
72					//e.preventDefault();
73
74					//change cursor to move while dragging
75					var dragHandle = e.target;
76					while (!$(dragHandle).is(opts.dragSelector)) {
77						if (dragHandle == this) return;
78						dragHandle = dragHandle.parentNode;
79					}
80					$(dragHandle).attr("data-cursor", $(dragHandle).css("cursor"));
81					$(dragHandle).css("cursor", "move");
82
83					//on mousedown wait for movement of mouse before triggering dragsort script (dragStart) to allow clicking of hyperlinks to work
84					var listElem = this;
85					var trigger = function() {
86						list.dragStart.call(listElem, e);
87						$(list.container).unbind("mousemove", trigger);
88					};
89					$(list.container).mousemove(trigger).mouseup(function() { $(list.container).unbind("mousemove", trigger); $(dragHandle).css("cursor", $(dragHandle).attr("data-cursor")); });
90				},
91
92				dragStart: function(e) {
93					if (list != null && list.draggedItem != null)
94						list.dropItem();
95
96					list = lists[$(this).attr("data-listidx")];
97					list.draggedItem = $(e.target).closest("[data-listidx] > " + opts.tagName)
98
99					//record current position so on dragend we know if the dragged item changed position or not, not using getItems to allow dragsort to restore dragged item to original location in relation to fixed items
100					list.draggedItem.attr("data-origpos", $(this).attr("data-listidx") + "-" + $(list.container).children().index(list.draggedItem));
101
102					//calculate mouse offset relative to draggedItem
103					var mt = parseInt(list.draggedItem.css("marginTop"));
104					var ml = parseInt(list.draggedItem.css("marginLeft"));
105					list.offset = list.draggedItem.offset();
106					list.offset.top = e.pageY - list.offset.top + (isNaN(mt) ? 0 : mt) - 1;
107					list.offset.left = e.pageX - list.offset.left + (isNaN(ml) ? 0 : ml) - 1;
108
109					//calculate box the dragged item can't be dragged outside of
110					if (!opts.dragBetween) {
111						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();
112						list.offsetLimit = $(list.container).offset();
113						list.offsetLimit.right = list.offsetLimit.left + $(list.container).outerWidth() - list.draggedItem.outerWidth();
114						list.offsetLimit.bottom = list.offsetLimit.top + containerHeight - list.draggedItem.outerHeight();
115					}
116
117					//create placeholder item
118					var h = list.draggedItem.height();
119					var w = list.draggedItem.width();
120					if (opts.tagName == "tr") {
121						list.draggedItem.children().each(function() { $(this).width($(this).width()); });
122						list.placeHolderItem = list.draggedItem.clone().attr("data-placeholder", true);
123						list.draggedItem.after(list.placeHolderItem);
124						//list.placeHolderItem.children().each(function() { $(this).css({ borderWidth:0, width: $(this).width() + 1, height: $(this).height() + 1 }).html("&nbsp;"); });
125						list.placeHolderItem.children().each(function() { $(this).html("&nbsp;"); });
126					} else {
127						list.draggedItem.after(opts.placeHolderTemplate);
128						list.placeHolderItem = list.draggedItem.next().css({ height: h, width: w }).attr("data-placeholder", true);
129					}
130
131					if (opts.tagName == "td") {
132						var listTable = list.draggedItem.closest("table").get(0);
133						$("<table id='" + listTable.id + "' style='border-width: 0px;' class='dragSortItem " + listTable.className + "'><tr></tr></table>").appendTo("body").children().append(list.draggedItem);
134					}
135
136					//style draggedItem while dragging
137					var orig = list.draggedItem.attr("style");
138					list.draggedItem.attr("data-origstyle", orig ? orig : "");
139					list.draggedItem.css({ position: "absolute", opacity: 0.8, "z-index": 999, height: h, width: w });
140
141					//auto-scroll setup
142					list.scroll = { moveX: 0, moveY: 0, maxX: $(document).width() - $(window).width(), maxY: $(document).height() - $(window).height() };
143					list.scroll.scrollY = window.setInterval(function() {
144						if (opts.scrollContainer != window) {
145							$(opts.scrollContainer).scrollTop($(opts.scrollContainer).scrollTop() + list.scroll.moveY);
146							return;
147						}
148						var t = $(opts.scrollContainer).scrollTop();
149						if (list.scroll.moveY > 0 && t < list.scroll.maxY || list.scroll.moveY < 0 && t > 0) {
150							$(opts.scrollContainer).scrollTop(t + list.scroll.moveY);
151							list.draggedItem.css("top", list.draggedItem.offset().top + list.scroll.moveY + 1);
152						}
153					}, 10);
154					list.scroll.scrollX = window.setInterval(function() {
155						if (opts.scrollContainer != window) {
156							$(opts.scrollContainer).scrollLeft($(opts.scrollContainer).scrollLeft() + list.scroll.moveX);
157							return;
158						}
159						var l = $(opts.scrollContainer).scrollLeft();
160						if (list.scroll.moveX > 0 && l < list.scroll.maxX || list.scroll.moveX < 0 && l > 0) {
161							$(opts.scrollContainer).scrollLeft(l + list.scroll.moveX);
162							list.draggedItem.css("left", list.draggedItem.offset().left + list.scroll.moveX + 1);
163						}
164					}, 10);
165
166					//misc
167					$(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
168					list.setPos(e.pageX, e.pageY);
169					$(document).bind("mousemove", list.swapItems);
170					$(document).bind("mouseup", list.dropItem);
171					if (opts.scrollContainer != window)
172						$(window).bind("wheel", list.wheel);
173				},
174
175				//set position of draggedItem
176				setPos: function(x, y) {
177					//remove mouse offset so mouse cursor remains in same place on draggedItem instead of top left corner
178					var top = y - this.offset.top;
179					var left = x - this.offset.left;
180
181					//limit top, left to within box draggedItem can't be dragged outside of
182					if (!opts.dragBetween) {
183						top = Math.min(this.offsetLimit.bottom, Math.max(top, this.offsetLimit.top));
184						left = Math.min(this.offsetLimit.right, Math.max(left, this.offsetLimit.left));
185					}
186
187					//adjust top & left calculations to parent offset
188					var parent = this.draggedItem.offsetParent().not("body").offset(); //offsetParent returns body even when it's static, if not static offset is only factoring margin
189					if (parent != null) {
190						top -= parent.top;
191						left -= parent.left;
192					}
193
194					//set x or y auto-scroll amount
195					if (opts.scrollContainer == window) {
196						y -= $(window).scrollTop();
197						x -= $(window).scrollLeft();
198						y = Math.max(0, y - $(window).height() + 5) + Math.min(0, y - 5);
199						x = Math.max(0, x - $(window).width() + 5) + Math.min(0, x - 5);
200					} else {
201						var cont = $(opts.scrollContainer);
202						var offset = cont.offset();
203						y = Math.max(0, y - cont.height() - offset.top) + Math.min(0, y - offset.top);
204						x = Math.max(0, x - cont.width() - offset.left) + Math.min(0, x - offset.left);
205					}
206
207					list.scroll.moveX = x == 0 ? 0 : x * opts.scrollSpeed / Math.abs(x);
208					list.scroll.moveY = y == 0 ? 0 : y * opts.scrollSpeed / Math.abs(y);
209
210					//move draggedItem to new mouse cursor location
211					this.draggedItem.css({ top: top, left: left });
212				},
213
214				//if scroll container is a div allow mouse wheel to scroll div instead of window when mouse is hovering over
215				wheel: function(e) {
216					if (list && opts.scrollContainer != window) {
217						var cont = $(opts.scrollContainer);
218						var offset = cont.offset();
219						e = e.originalEvent;
220						if (e.clientX > offset.left && e.clientX < offset.left + cont.width() && e.clientY > offset.top && e.clientY < offset.top + cont.height()) {
221							var deltaY = (e.deltaMode == 0 ? 1 : 10) * e.deltaY;
222							cont.scrollTop(cont.scrollTop() + deltaY);
223							e.preventDefault();
224						}
225					}
226				},
227
228				//build a table recording all the positions of the moveable list items
229				buildPositionTable: function() {
230					var pos = [];
231					this.getItems().not([list.draggedItem[0], list.placeHolderItem[0]]).each(function(i) {
232						var loc = $(this).offset();
233						loc.right = loc.left + $(this).outerWidth();
234						loc.bottom = loc.top + $(this).outerHeight();
235						loc.elm = this;
236						pos[i] = loc;
237					});
238					this.pos = pos;
239				},
240
241				dropItem: function() {
242					if (list.draggedItem == null)
243						return;
244
245					//list.draggedItem.attr("style", "") doesn't work on IE8 and jQuery 1.5 or lower
246					//list.draggedItem.removeAttr("style") doesn't work on chrome and jQuery 1.6 (works jQuery 1.5 or lower)
247					var orig = list.draggedItem.attr("data-origstyle");
248					list.draggedItem.attr("style", orig);
249					if (orig == "")
250						list.draggedItem.removeAttr("style");
251					list.draggedItem.removeAttr("data-origstyle");
252
253					list.styleDragHandlers(true);
254
255					list.placeHolderItem.before(list.draggedItem);
256					list.placeHolderItem.remove();
257
258					$("[data-droptarget], .dragSortItem").remove();
259
260					window.clearInterval(list.scroll.scrollY);
261					window.clearInterval(list.scroll.scrollX);
262
263					//if position changed call dragEnd
264					if (list.draggedItem.attr("data-origpos") != $(lists).index(list) + "-" + $(list.container).children().index(list.draggedItem))
265						if (opts.dragEnd.apply(list.draggedItem) == false) { //if dragEnd returns false revert order
266							var pos = list.draggedItem.attr("data-origpos").split('-');
267							var nextItem = $(lists[pos[0]].container).children().not(list.draggedItem).eq(pos[1]);
268							if (nextItem.length > 0)
269								nextItem.before(list.draggedItem);
270							else if (pos[1] == 0) //was the only item in list
271								$(lists[pos[0]].container).prepend(list.draggedItem);
272							else //was the last item in list
273								$(lists[pos[0]].container).append(list.draggedItem);
274						}
275					list.draggedItem.removeAttr("data-origpos");
276
277					list.draggedItem = null;
278					$(document).unbind("mousemove", list.swapItems);
279					$(document).unbind("mouseup", list.dropItem);
280					if (opts.scrollContainer != window)
281						$(window).unbind("wheel", list.wheel);
282					return false;
283				},
284
285				//swap the draggedItem (represented visually by placeholder) with the list item the it has been dragged on top of
286				swapItems: function(e) {
287					if (list.draggedItem == null)
288						return false;
289
290					//move draggedItem to mouse location
291					list.setPos(e.pageX, e.pageY);
292
293					//retrieve list and item position mouse cursor is over
294					var ei = list.findPos(e.pageX, e.pageY);
295					var nlist = list;
296					for (var i = 0; ei == -1 && opts.dragBetween && i < lists.length; i++) {
297						ei = lists[i].findPos(e.pageX, e.pageY);
298						nlist = lists[i];
299					}
300
301					//if not over another moveable list item return
302					if (ei == -1)
303						return false;
304
305					//save fixed items locations
306					var children = function() { return $(nlist.container).children().not(nlist.draggedItem); };
307					var fixed = children().not(opts.itemSelector).each(function(i) { this.idx = children().index(this); });
308
309					//if moving draggedItem up or left place placeHolder before list item the dragged item is hovering over otherwise place it after
310					if (lastPos == null || lastPos.top > list.draggedItem.offset().top || lastPos.left > list.draggedItem.offset().left)
311						$(nlist.pos[ei].elm).before(list.placeHolderItem);
312					else
313						$(nlist.pos[ei].elm).after(list.placeHolderItem);
314
315					//restore fixed items location
316					fixed.each(function() {
317						var elm = children().eq(this.idx).get(0);
318						if (this != elm && children().index(this) < this.idx)
319							$(this).insertAfter(elm);
320						else if (this != elm)
321							$(this).insertBefore(elm);
322					});
323
324					//misc
325					$(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
326					lastPos = list.draggedItem.offset();
327					return false;
328				},
329
330				//returns the index of the list item the mouse is over
331				findPos: function(x, y) {
332					for (var i = 0; i < this.pos.length; i++) {
333						if (this.pos[i].left < x && this.pos[i].right > x && this.pos[i].top < y && this.pos[i].bottom > y)
334							return i;
335					}
336					return -1;
337				},
338
339				//create drop targets which are placeholders at the end of other lists to allow dragging straight to the last position
340				createDropTargets: function() {
341					if (!opts.dragBetween)
342						return;
343
344					$(lists).each(function() {
345						var ph = $(this.container).find("[data-placeholder]");
346						var dt = $(this.container).find("[data-droptarget]");
347						if (ph.length > 0 && dt.length > 0)
348							dt.remove();
349						else if (ph.length == 0 && dt.length == 0) {
350							if (opts.tagName == "td")
351								$(opts.placeHolderTemplate).attr("data-droptarget", true).appendTo(this.container);
352							else
353								//list.placeHolderItem.clone().removeAttr("data-placeholder") crashes in IE7 and jquery 1.5.1 (doesn't in jquery 1.4.2 or IE8)
354								$(this.container).append(list.placeHolderItem.removeAttr("data-placeholder").clone().attr("data-droptarget", true));
355
356							list.placeHolderItem.attr("data-placeholder", true);
357						}
358					});
359				}
360			};
361
362			newList.init();
363			lists.push(newList);
364		});
365
366		return this;
367	};
368
369	$.fn.dragsort.defaults = {
370		tagName:"",
371		itemSelector: "",
372		dragSelector: "",
373		dragSelectorExclude: "input, textarea",
374		dragEnd: function() { },
375		dragBetween: false,
376		placeHolderTemplate: "",
377		scrollContainer: window,
378		scrollSpeed: 5
379	};
380
381})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.