/[drupal]/contributions/modules/ui/javascript/ui.sortable.js
ViewVC logotype

Diff of /contributions/modules/ui/javascript/ui.sortable.js

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.1, Sun Sep 2 20:21:42 2007 UTC revision 1.2, Mon Sep 17 03:42:34 2007 UTC
# Line 6  if (window.Node && Node.prototype && !No Line 6  if (window.Node && Node.prototype && !No
6    
7  (function($) {  (function($) {
8    
9            //Make nodes selectable by expression
10            $.extend($.expr[':'], { sortable: "(' '+a.className+' ').indexOf(' ui-sortable ')" });
11    
12          $.fn.sortable = function(o) {          $.fn.sortable = function(o) {
13                  return this.each(function() {                  return this.each(function() {
14                          new $.ui.sortable(this,o);                          new $.ui.sortable(this,o);
15                  });                  });
         },  
         $.fn.stopAll = function() {  
                 return this.each(function(){  
                         if (this.queue) {  
                                 if (this.queue['fx']) {  
                                         if (this.queue['fx'][0]) {  
                                                 this.queue['fx'] = [this.queue['fx'][0]];  
                                                 this.queue['fx'][0].startTime = (new Date()).getTime() - 1000000000;  
                                         }  
                                 }  
                         }  
                 });  
16          }          }
17    
18            //Macros for external methods that support chaining
19            var methods = "destroy,enable,disable,refresh".split(",");
20            for(var i=0;i<methods.length;i++) {
21                    var cur = methods[i], f;
22                    eval('f = function() { var a = arguments; return this.each(function() { if(jQuery(this).is(".ui-sortable")) jQuery.data(this, "ui-sortable")["'+cur+'"](a); }); }');
23                    $.fn["sortable"+cur.substr(0,1).toUpperCase()+cur.substr(1)] = f;
24            };
25    
26            //get instance method
27            $.fn.sortableInstance = function() {
28                    if($(this[0]).is(".ui-sortable")) return $.data(this[0], "ui-sortable");
29                    return false;
30            };
31    
32          $.ui.sortable = function(el,o) {          $.ui.sortable = function(el,o) {
33    
34                  this.element = el;                  this.element = el;
35                  this.set = [];                  this.set = [];
36                  var options = {};                  var options = {};
37                  var self = this;                  var self = this;
38                    $.data(this.element, "ui-sortable", this);
39                    $(el).addClass("ui-sortable");
40    
41                  $.extend(options, o);                  $.extend(options, o);
42                  $.extend(options, {                  $.extend(options, {
43                          items: options.items || '> li',                          items: options.items || '> li',
44                            smooth: options.smooth != undefined ? options.smooth : true,
45                          helper: 'clone',                          helper: 'clone',
46                          containment: options.containment ? (options.containment == 'sortable' ? el : options.containment) : null,                          containment: options.containment ? (options.containment == 'sortable' ? el : options.containment) : null,
47                          zIndex: options.zIndex || 1000,                          zIndex: options.zIndex || 1000,
# Line 45  if (window.Node && Node.prototype && !No Line 53  if (window.Node && Node.prototype && !No
53                          },                          },
54                          _drag: function(h,p,c,t,e) {                          _drag: function(h,p,c,t,e) {
55                                  self.drag.apply(t, [self, e]); // Trigger the onStart callback                                  self.drag.apply(t, [self, e]); // Trigger the onStart callback
56                            },
57                            startCondition: function() {
58                                    return !self.disabled;
59                          }                          }
60                  });                  });
61    
62                  //Get the items                  //Get the items
63                  self.set = $(options.items, el).each(function() {                  var items = $(options.items, el);
                         new $.ui.mouseInteraction(this,options);  
                 });  
64    
65                  //Let's determine the floating mode                  //Let's determine the floating mode
66                  options.floating = /left|right/.test(self.set.css('float'));                  options.floating = /left|right/.test(items.css('float'));
                 options.animated = options.animated && self.set.css('position') == 'relative';  
67    
68                  //Let's determine the parent's offset                  //Let's determine the parent's offset
69                  if($(el).css('position') == 'static') $(el).css('position', 'relative');                  if($(el).css('position') == 'static') $(el).css('position', 'relative');
70                  options.offset = $(el).offset({ border: false });                  options.offset = $(el).offset({ border: false });
71    
72                    items.each(function() {
73                            new $.ui.mouseInteraction(this,options);
74                    });
75    
76                    //Add current items to the set
77                    items.each(function() {
78                            self.set.push([this,null]);
79                    });
80    
81                  this.options = options;                  this.options = options;
82          }          }
83    
84          $.extend($.ui.sortable.prototype, {          $.extend($.ui.sortable.prototype, {
85                  plugins: {},                  plugins: {},
                 pos: null,  
                 opos: null,  
86                  currentTarget: null,                  currentTarget: null,
87                  lastTarget: null,                  lastTarget: null,
                 helper: null,  
                 timer: null,  
                 slowMode: false,  
                 element: null,  
                 init: false,  
88                  prepareCallbackObj: function(self, that) {                  prepareCallbackObj: function(self, that) {
89                          return {                          return {
90                                  helper: self.helper,                                  helper: self.helper,
# Line 110  if (window.Node && Node.prototype && !No Line 120  if (window.Node && Node.prototype && !No
120    
121                  },                  },
122                  destroy: function() {                  destroy: function() {
123                            $(this.element).removeClass("ui-sortable").removeClass("ui-sortable-disabled");
124                            $(this.options.items, this.element).mouseInteractionDestroy();
125    
126                  },                  },
127                    enable: function() {
128                            $(this.element).removeClass("ui-sortable-disabled");
129                            this.disabled = false;
130                    },
131                    disable: function() {
132                            $(this.element).addClass("ui-sortable-disabled");
133                            this.disabled = true;
134                    },
135                  start: function(that, e) {                  start: function(that, e) {
136    
137                          var o = this.options;                          var o = this.options;
138                          //cache each elements position. When we insert an element before or after the actual position will not coutn anymore TODO cache elements position for each active sortable  
                         that.cachedItemsPos = [];  
                         //remember container position  
                         that.pos = $(that.element).offset({ border: false});  
                         that.set = $(that.options.items, that.element).not(':last').each(function(nr){  
                                 that.cachedItemsPos[nr] = {  
                                         x: this.offsetLeft,  
                                         y: this.offsetTop,  
                                         w: this.offsetWidth,  
                                         h: this.offsetHeight  
                                 };  
                         });  
                         o.lastOverlap = -1;  
                         o.movedElement = null;  
   
   
                         $.ui.plugin.call('start', this);  
139                          if(o.hoverClass) {                          if(o.hoverClass) {
140                                  that.helper = $('<div class="'+o.hoverClass+'"></div>').appendTo('body').css({                                  that.helper = $('<div class="'+o.hoverClass+'"></div>').appendTo('body').css({
141                                          height: this.element.offsetHeight+'px',                                          height: this.element.offsetHeight+'px',
# Line 139  if (window.Node && Node.prototype && !No Line 143  if (window.Node && Node.prototype && !No
143                                          position: 'absolute'                                          position: 'absolute'
144                                  });                                  });
145                          }                          }
146    
147                          if(o.zIndex) {                          if(o.zIndex) {
148                                  if($(this.helper).css("zIndex")) o.ozIndex = $(this.helper).css("zIndex");                                  if($(this.helper).css("zIndex")) o.ozIndex = $(this.helper).css("zIndex");
149                                  $(this.helper).css('zIndex', o.zIndex);                                  $(this.helper).css('zIndex', o.zIndex);
150                          }                          }
                         that.firstSibling = $(this.element).prev()[0];  
151    
152                          if(o.start) o.start.apply(this.element, [this.helper, this.pos, o.cursorAt, this]);                          that.firstSibling = $(this.element).prev()[0];
153    
154                          $(this.element).triggerHandler("sortstart", [e, that.prepareCallbackObj(this)], o.start);                          $(this.element).triggerHandler("sortstart", [e, that.prepareCallbackObj(this)], o.start);
155                          $(this.element).css('visibility', 'hidden');                          $(this.element).css('visibility', 'hidden');
156    
157                          return false;                          return false;
158    
159                  },                  },
160                  stop: function(that, e) {                  stop: function(that, e) {
161    
162                          var o = this.options;                          var o = this.options;
163                            var self = this;
164    
165                          $.ui.plugin.call('stop', this);  
166                          $(this.element).css('visibility', 'visible');                          if(o.smooth) {
167                                    var os = $(this.element).offset();
168                          if(that.helper)                                  o.beQuietAtEnd = true;
169                                  that.helper.remove();                                  $(this.helper).animate({ left: os.left - o.po.left, top: os.top - o.po.top }, 500, stopIt);
170                            } else {
171                          if(o.ozIndex)                                  stopIt();
172                                  $(this.helper).css('zIndex', o.ozIndex);                          }
   
173    
174                          //Let's see if the position in DOM has changed                          function stopIt() {
175                          if($(this.element).prev()[0] != that.firstSibling) {  
176                                  $(this.element).triggerHandler("sortupdate", [e, that.prepareCallbackObj(this, that)], o.update);                                  $(self.element).css('visibility', 'visible');
177                                    if(that.helper) that.helper.remove();
178                                    if(self.helper != self.element) $(self.helper).remove();
179    
180                                    if(o.ozIndex)
181                                            $(self.helper).css('zIndex', o.ozIndex);
182    
183    
184                                    //Let's see if the position in DOM has changed
185                                    if($(self.element).prev()[0] != that.firstSibling) {
186                                            //$(self.element).triggerHandler("sortupdate", [e, that.prepareCallbackObj(self, that)], o.update);
187                                    }
188    
189                          }                          }
190                          //clear previous cache TODO: clear al active sortables  
191                          that.cachedItemsPos = null;  
                         that.pos = null;  
                         o.lastOverlap = false;  
192                          return false;                          return false;
193    
194                  },                  },
195                  drag: function(that, e) {                  drag: function(that, e) {
196                          // remember the dragged element. We need this to exclude this one from items we check against  
                         draggedEl = this.element;  
197                          var o = this.options;                          var o = this.options;
                         this.pos = [this.pos[0]-o.cursorAt.left, this.pos[1]-o.cursorAt.top];  
                         $.ui.plugin.call('drag', this);  
198    
199                            this.pos = [this.pos[0]-(o.cursorAt.left ? o.cursorAt.left : 0), this.pos[1]-(o.cursorAt.top ? o.cursorAt.top : 0)];
200                          var nv =  $(this.element).triggerHandler("sort", [e, that.prepareCallbackObj(this)], o.sort);                          var nv =  $(this.element).triggerHandler("sort", [e, that.prepareCallbackObj(this)], o.sort);
201                          var nl = (nv && nv.left) ? nv.left :  this.pos[0];                          var nl = (nv && nv.left) ? nv.left :  this.pos[0];
202                          var nt = (nv && nv.top) ? nv.top :  this.pos[1];                          var nt = (nv && nv.top) ? nv.top :  this.pos[1];
203                          //overlaped element  
204                          var targetIndex = null;  
205                          //overlap index                          var m = that.set;
206                          var targetOverlap = null;                          var p = this.pos[1];
207    
208                          that.set.each(function(nr){                          for(var i=0;i<m.length;i++) {
209                                  if (o.lastOverlap == this || targetIndex != null)  
210                                          return;                                  var ci = $(m[i][0]); var cio = m[i][0];
211                                  if(that.options.floating) {                                  if(this.element.contains(cio)) continue;
212                                          elPosition = that.pos.left + that.cachedItemsPos[nr].x;                                  var cO = ci.offset(); //TODO: Caching
213                                          elDimension = that.cachedItemsPos[nr].w;                                  cO = { top: cO.top, left: cO.left };
214                                          curPosition = e.pageX;  
215                                          overlapY = (e.pageY - that.pos.top - that.cachedItemsPos[nr].y) / that.cachedItemsPos[nr].h;                                  var mb = function(e) { if(true || o.lba != cio) { ci.before(e); o.lba = cio; } }
216                                          overlapY = overlapY >= 0 && overlapY <=1;                                  var ma = function(e) { if(true || o.laa != cio) { ci.after(e); o.laa = cio; } }
217    
218                                    if(o.floating) {
219    
220                                            var overlap = ((cO.left - (this.pos[0]+(this.options.po ? this.options.po.left : 0)))/this.helper.offsetWidth);
221    
222                                            if(!(cO.top < this.pos[1]+(this.options.po ? this.options.po.top : 0) + cio.offsetHeight/2 && cO.top + cio.offsetHeight > this.pos[1]+(this.options.po ? this.options.po.top : 0) + cio.offsetHeight/2)) continue;
223    
224                                  } else {                                  } else {
225                                          elPosition = that.pos.top + that.cachedItemsPos[nr].y;  
226                                          elDimension = that.cachedItemsPos[nr].h;                                          var overlap = ((cO.top - (this.pos[1]+(this.options.po ? this.options.po.top : 0)))/this.helper.offsetHeight);
227                                          curPosition = e.pageY;  
228                                          overlapY = true;                                          if(!(cO.left < this.pos[0]+(this.options.po ? this.options.po.left : 0) + cio.offsetWidth/2 && cO.left + cio.offsetWidth > this.pos[0]+(this.options.po ? this.options.po.left : 0) + cio.offsetWidth/2)) continue;
229                                  }  
                                 overlap = (curPosition - elPosition) / elDimension;  
                                 if (overlap >= 0 && overlap <= 1 && overlapY) {  
                                         targetIndex = nr;  
                                         targetOverlap = overlap;  
                                 }  
                         });  
                         //one element was overlaped  
                         if (targetIndex != null) {  
                                 where = 'after';  
                                 elementIndex = that.set.index(this.element);  
                                 o.lastOverlap = that.set[targetIndex];  
                                 if (elementIndex > targetIndex || that.set[targetIndex] == this.element) {  
                                         targetIndex --;  
                                 }  
                                 if (targetIndex < 0) {  
                                         targetIndex = 0;  
                                         where = 'before';  
                                 }  
                                 if (o.animated) {  
                                         toMoveIndex = targetIndex;  
                                         if (o.lastIndex > targetIndex) {  
                                                 toMoveIndex = o.lastIndex ;  
                                         }  
                                         if (o.movedElement && o.movedElement[0] == that.set[toMoveIndex]) {  
                                                 o.movedElement  
                                                         .stopAll()  
                                                         .css({  
                                                                 top: 0,  
                                                                 left: 0  
                                                         });  
                                         }  
                                         o.movedElement = $(that.set[toMoveIndex]);  
                                         oldPos = {  
                                                 top: o.movedElement[0].offsetTop,  
                                                 left: o.movedElement[0].offsetLeft  
                                         };  
230                                  }                                  }
                                 $(that.set[targetIndex])[where](this.element);  
231    
232                                  if (o.animated) {                                  if(overlap >= 0 && overlap <= 0.5) { //Overlapping at top
233                                          o.movedElement.css({                                          ci.prev().length ? ma(this.element) : mb(this.element);
                                                 top: oldPos.top - o.movedElement[0].offsetTop + 'px',  
                                                 left: oldPos.left - o.movedElement[0].offsetLeft + 'px'  
                                         }).animate({  
                                                 top: 0,  
                                                 left: 0  
                                         }, 500);  
                                         o.lastIndex = targetIndex;  
234                                  }                                  }
235    
236                                    if(overlap < 0 && overlap > -0.5) { //Overlapping at bottom
237                                            ci.next()[0] == this.element ? mb(this.element) : ma(this.element);
238                                    }
239    
240                          }                          }
241    
242                          //Let's see if the position in DOM has changed                          //Let's see if the position in DOM has changed
# Line 262  if (window.Node && Node.prototype && !No Line 246  if (window.Node && Node.prototype && !No
246                          }                          }
247    
248                          if(that.helper) { //reposition helper if available                          if(that.helper) { //reposition helper if available
249                                  var to = $(this.element).offsetLite({ border: false });                                  var to = $(this.element).offset();
250                                  that.helper.css({                                  that.helper.css({
251                                          top: to.top+'px',                                          top: to.top+'px',
252                                          left: to.left+'px'                                          left: to.left+'px'
253                                  });                                  });
254                          }                          }
255    
   
256                          $(this.helper).css('left', nl+'px').css('top', nt+'px'); // Stick the helper to the cursor                          $(this.helper).css('left', nl+'px').css('top', nt+'px'); // Stick the helper to the cursor
257                          return false;                          return false;
258    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

  ViewVC Help
Powered by ViewVC 1.1.2