2 * Interface Elements for jQuery
\r
5 * http://interface.eyecon.ro
\r
7 * Copyright (c) 2006 Stefan Petre
\r
8 * Dual licensed under the MIT (MIT-LICENSE.txt)
\r
9 * and GPL (GPL-LICENSE.txt) licenses.
\r
15 * Allows you to resort elements within a container by dragging and dropping. Requires
\r
16 * the Draggables and Droppables plugins. The container and each item inside the container
\r
17 * must have an ID. Sortables are especially useful for lists.
\r
19 * @see Plugins/Interface/Draggable
\r
20 * @see Plugins/Interface/Droppable
\r
21 * @author Stefan Petre
\r
23 * @cat Plugins/Interface
\r
24 * @param Hash options A hash of options
\r
25 * @option String accept The class name for items inside the container (mandatory)
\r
26 * @option String activeclass The class for the container when one of its items has started to move
\r
27 * @option String hoverclass The class for the container when an acceptable item is inside it
\r
28 * @option String helperclass The helper is used to point to the place where the item will be
\r
29 * moved. This is the class for the helper.
\r
30 * @option Float opacity Opacity (between 0 and 1) of the item while being dragged
\r
31 * @option Boolean ghosting When true, the sortable is ghosted when dragged
\r
32 * @option String tolerance Either 'pointer', 'intersect', or 'fit'. See Droppable for more details
\r
33 * @option Boolean fit When true, sortable must be inside the container in order to drop
\r
34 * @option Integer fx Duration for the effect applied to the sortable
\r
35 * @option Function onchange Callback that gets called when the sortable list changed. It takes
\r
36 * an array of serialized elements
\r
37 * @option Boolean floats True if the sorted elements are floated
\r
38 * @option String containment Use 'parent' to constrain the drag to the container
\r
39 * @option String axis Use 'horizontally' or 'vertically' to constrain dragging to an axis
\r
40 * @option String handle The jQuery selector that indicates the draggable handle
\r
41 * @option DOMElement handle The node that indicates the draggable handle
\r
42 * @option Function onHover Callback that is called when an acceptable item is dragged over the
\r
43 * container. Gets the hovering DOMElement as a parameter
\r
44 * @option Function onOut Callback that is called when an acceptable item leaves the container.
\r
45 * Gets the leaving DOMElement as a parameter
\r
46 * @option Object cursorAt The mouse cursor will be moved to the offset on the dragged item
\r
47 * indicated by the object, which takes "top", "bottom", "left", and
\r
49 * @option Function onStart Callback function triggered when the dragging starts
\r
50 * @option Function onStop Callback function triggered when the dragging stops
\r
51 * @example $('ul').Sortable(
\r
53 * accept : 'sortableitem',
\r
54 * activeclass : 'sortableactive',
\r
55 * hoverclass : 'sortablehover',
\r
56 * helperclass : 'sorthelper',
\r
71 if (jQuery.iDrag.dragged == null) {
\r
74 var shs, margins,c, cs;
\r
76 jQuery.iSort.helper.get(0).className = jQuery.iDrag.dragged.dragCfg.hpc;
\r
77 shs = jQuery.iSort.helper.get(0).style;
\r
78 shs.display = 'block';
\r
79 jQuery.iSort.helper.oC = jQuery.extend(
\r
80 jQuery.iUtil.getPosition(jQuery.iSort.helper.get(0)),
\r
81 jQuery.iUtil.getSize(jQuery.iSort.helper.get(0))
\r
84 shs.width = jQuery.iDrag.dragged.dragCfg.oC.wb + 'px';
\r
85 shs.height = jQuery.iDrag.dragged.dragCfg.oC.hb + 'px';
\r
86 //shs.cssFloat = jQuery.iDrag.dragged.dragCfg.oF;
\r
87 margins = jQuery.iUtil.getMargins(jQuery.iDrag.dragged);
\r
88 shs.marginTop = margins.t;
\r
89 shs.marginRight = margins.r;
\r
90 shs.marginBottom = margins.b;
\r
91 shs.marginLeft = margins.l;
\r
92 if (jQuery.iDrag.dragged.dragCfg.ghosting == true) {
\r
93 c = jQuery.iDrag.dragged.cloneNode(true);
\r
95 cs.marginTop = '0px';
\r
96 cs.marginRight = '0px';
\r
97 cs.marginBottom = '0px';
\r
98 cs.marginLeft = '0px';
\r
99 cs.display = 'block';
\r
100 jQuery.iSort.helper.empty().append(c);
\r
102 jQuery(jQuery.iDrag.dragged).after(jQuery.iSort.helper.get(0));
\r
103 jQuery.iDrag.dragged.style.display = 'none';
\r
106 check : function (e)
\r
108 if (!e.dragCfg.so && jQuery.iDrop.overzone.sortable) {
\r
109 if (e.dragCfg.onStop)
\r
110 e.dragCfg.onStop.apply(dragged);
\r
111 jQuery(e).css('position', e.dragCfg.initialPosition || e.dragCfg.oP);
\r
112 jQuery(e).DraggableDestroy();
\r
113 jQuery(jQuery.iDrop.overzone).SortableAddItem(e);
\r
115 jQuery.iSort.helper.removeClass(e.dragCfg.hpc).html(' ');
\r
116 jQuery.iSort.inFrontOf = null;
\r
117 var shs = jQuery.iSort.helper.get(0).style;
\r
118 shs.display = 'none';
\r
119 jQuery.iSort.helper.after(e);
\r
120 if (e.dragCfg.fx > 0) {
\r
121 jQuery(e).fadeIn(e.dragCfg.fx);
\r
123 jQuery('body').append(jQuery.iSort.helper.get(0));
\r
126 for(var i=0; i<jQuery.iSort.changed.length; i++){
\r
127 var iEL = jQuery.iDrop.zones[jQuery.iSort.changed[i]].get(0);
\r
128 var id = jQuery.attr(iEL, 'id');
\r
129 var ser = jQuery.iSort.serialize(id);
\r
130 if (iEL.dropCfg.os != ser.hash) {
\r
131 iEL.dropCfg.os = ser.hash;
\r
132 if (fnc == false && iEL.dropCfg.onChange) {
\r
133 fnc = iEL.dropCfg.onChange;
\r
136 ts[ts.length] = ser;
\r
139 jQuery.iSort.changed = [];
\r
140 if (fnc != false && ts.length > 0) {
\r
145 checkhover : function(e,o)
\r
147 if (!jQuery.iDrag.dragged)
\r
151 if ( e.dropCfg.el.size() > 0) {
\r
152 for (i = e.dropCfg.el.size(); i >0; i--) {
\r
153 if (e.dropCfg.el.get(i-1) != jQuery.iDrag.dragged) {
\r
154 if (!e.sortCfg.floats) {
\r
156 (e.dropCfg.el.get(i-1).pos.y + e.dropCfg.el.get(i-1).pos.hb/2) > jQuery.iDrag.dragged.dragCfg.ny
\r
158 cur = e.dropCfg.el.get(i-1);
\r
164 (e.dropCfg.el.get(i-1).pos.x + e.dropCfg.el.get(i-1).pos.wb/2) > jQuery.iDrag.dragged.dragCfg.nx &&
\r
165 (e.dropCfg.el.get(i-1).pos.y + e.dropCfg.el.get(i-1).pos.hb/2) > jQuery.iDrag.dragged.dragCfg.ny
\r
167 cur = e.dropCfg.el.get(i-1);
\r
173 //helpos = jQuery.iUtil.getPos(jQuery.iSort.helper.get(0));
\r
174 if (cur && jQuery.iSort.inFrontOf != cur) {
\r
175 jQuery.iSort.inFrontOf = cur;
\r
176 jQuery(cur).before(jQuery.iSort.helper.get(0));
\r
177 } else if(!cur && (jQuery.iSort.inFrontOf != null || jQuery.iSort.helper.get(0).parentNode != e) ) {
\r
178 jQuery.iSort.inFrontOf = null;
\r
179 jQuery(e).append(jQuery.iSort.helper.get(0));
\r
181 jQuery.iSort.helper.get(0).style.display = 'block';
\r
184 measure : function (e)
\r
186 if (jQuery.iDrag.dragged == null) {
\r
189 e.dropCfg.el.each (
\r
192 this.pos = jQuery.extend(
\r
193 jQuery.iUtil.getSizeLite(this),
\r
194 jQuery.iUtil.getPositionLite(this)
\r
200 serialize : function(s)
\r
206 if (jQuery.iSort.collected[s] ) {
\r
208 jQuery('#' + s + ' .' + jQuery.iSort.collected[s]).each(
\r
211 if (h.length > 0) {
\r
214 h += s + '[]=' + jQuery.attr(this,'id');
\r
215 o[s][o[s].length] = jQuery.attr(this,'id');
\r
220 if (jQuery.iSort.collected[s[a]] ) {
\r
222 jQuery('#' + s[a] + ' .' + jQuery.iSort.collected[s[a]]).each(
\r
225 if (h.length > 0) {
\r
228 h += s[a] + '[]=' + jQuery.attr(this,'id');
\r
229 o[s[a]][o[s[a]].length] = jQuery.attr(this,'id');
\r
236 for ( i in jQuery.iSort.collected){
\r
238 jQuery('#' + i + ' .' + jQuery.iSort.collected[i]).each(
\r
241 if (h.length > 0) {
\r
244 h += i + '[]=' + jQuery.attr(this,'id');
\r
245 o[i][o[i].length] = jQuery.attr(this,'id');
\r
250 return {hash:h, o:o};
\r
253 addItem : function (e)
\r
255 if ( !e.childNodes ) {
\r
261 if(!this.sortCfg || !jQuery(e).is('.' + this.sortCfg.accept))
\r
262 jQuery(e).addClass(this.sortCfg.accept);
\r
263 jQuery(e).Draggable(this.sortCfg.dragCfg);
\r
268 destroy: function()
\r
273 jQuery('.' + this.sortCfg.accept).DraggableDestroy();
\r
274 jQuery(this).DroppableDestroy();
\r
275 this.sortCfg = null;
\r
276 this.isSortable = null;
\r
281 build : function (o)
\r
283 if (o.accept && jQuery.iUtil && jQuery.iDrag && jQuery.iDrop) {
\r
284 if (!jQuery.iSort.helper) {
\r
285 jQuery('body',document).append('<div id="sortHelper"> </div>');
\r
286 jQuery.iSort.helper = jQuery('#sortHelper');
\r
287 jQuery.iSort.helper.get(0).style.display = 'none';
\r
292 activeclass : o.activeclass ? o.activeclass : false,
\r
293 hoverclass : o.hoverclass ? o.hoverclass : false,
\r
294 helperclass : o.helperclass ? o.helperclass : false,
\r
295 /*onDrop: function (drag, fx)
\r
297 jQuery.iSort.helper.after(drag);
\r
299 jQuery(drag).fadeIn(fx);
\r
302 onHover: o.onHover||o.onhover,
\r
303 onOut: o.onOut||o.onout,
\r
305 onChange : o.onChange||o.onchange,
\r
306 fx : o.fx ? o.fx : false,
\r
307 ghosting : o.ghosting ? true : false,
\r
308 tolerance: o.tolerance ? o.tolerance : 'intersect'
\r
316 revert : o.revert? true : false,
\r
318 opacity : o.opacity ? parseFloat(o.opacity) : false,
\r
319 hpc : o.helperclass ? o.helperclass : false,
\r
320 fx : o.fx ? o.fx : false,
\r
322 ghosting : o.ghosting ? true : false,
\r
323 handle: o.handle ? o.handle : null,
\r
324 containment: o.containment ? o.containment : null,
\r
325 onStart : o.onStart && o.onStart.constructor == Function ? o.onStart : false,
\r
326 onDrag : o.onDrag && o.onDrag.constructor == Function ? o.onDrag : false,
\r
327 onStop : o.onStop && o.onStop.constructor == Function ? o.onStop : false,
\r
328 axis : /vertically|horizontally/.test(o.axis) ? o.axis : false,
\r
329 snapDistance : o.snapDistance ? parseInt(o.snapDistance)||0 : false,
\r
330 cursorAt: o.cursorAt ? o.cursorAt : false
\r
332 jQuery('.' + o.accept, this).Draggable(dragCfg);
\r
333 this.isSortable = true;
\r
336 revert : o.revert? true : false,
\r
338 opacity : o.opacity ? parseFloat(o.opacity) : false,
\r
339 hpc : o.helperclass ? o.helperclass : false,
\r
340 fx : o.fx ? o.fx : false,
\r
342 ghosting : o.ghosting ? true : false,
\r
343 handle: o.handle ? o.handle : null,
\r
344 containment: o.containment ? o.containment : null,
\r
345 floats: o.floats ? true : false,
\r
356 Sortable : jQuery.iSort.build,
\r
358 * A new item can be added to a sortable by adding it to the DOM and then adding it via
\r
359 * SortableAddItem.
\r
361 * @name SortableAddItem
\r
362 * @param DOMElement elem A DOM Element to add to the sortable list
\r
363 * @example $('#sortable1').append('<li id="newitem">new item</li>')
\r
364 * .SortableAddItem($("#new_item")[0])
\r
366 * @cat Plugins/Interface
\r
368 SortableAddItem : jQuery.iSort.addItem,
\r
370 * Destroy a sortable
\r
372 * @name SortableDestroy
\r
373 * @example $('#sortable1').SortableDestroy();
\r
375 * @cat Plugins/Interface
\r
377 SortableDestroy: jQuery.iSort.destroy
\r
382 * This function returns the hash and an object (can be used as arguments for $.post) for every
\r
383 * sortable in the page or specific sortables. The hash is based on the 'id' attributes of
\r
384 * container and items.
\r
386 * @params String sortable The id of the sortable to serialize
\r
387 * @name $.SortSerialize
\r
389 * @cat Plugins/Interface
\r
392 jQuery.SortSerialize = jQuery.iSort.serialize;