|
123 | 123 | result.children = $children |
124 | 124 | } |
125 | 125 |
|
126 | | - delete result.subContainer |
127 | | - delete result[pluginName] |
| 126 | + delete result.subContainers |
| 127 | + delete result.sortable |
128 | 128 |
|
129 | 129 | return result |
130 | 130 | }, |
|
139 | 139 | top: 0, |
140 | 140 | bottom: 0, |
141 | 141 | right:0 |
142 | | - } |
| 142 | + }, |
143 | 143 | eventNames = { |
144 | 144 | start: "touchstart.sortable mousedown.sortable", |
145 | 145 | drop: "touchend.sortable touchcancel.sortable mouseup.sortable", |
146 | 146 | drag: "touchmove.sortable mousemove.sortable", |
147 | 147 | scroll: "scroll.sortable" |
148 | | - } |
| 148 | + }, |
| 149 | + subContainerKey = "subContainers" |
149 | 150 |
|
150 | 151 | /* |
151 | 152 | * a is Array [left, right, top, bottom] |
|
209 | 210 | this.options = $.extend({}, groupDefaults, options) |
210 | 211 | this.containers = [] |
211 | 212 |
|
212 | | - if(!this.options.parentContainer){ |
| 213 | + if(!this.options.rootGroup){ |
213 | 214 | this.scrollProxy = $.proxy(this.scroll, this) |
214 | 215 | this.dragProxy = $.proxy(this.drag, this) |
215 | 216 | this.dropProxy = $.proxy(this.drop, this) |
|
221 | 222 | } |
222 | 223 |
|
223 | 224 | ContainerGroup.get = function (options) { |
224 | | - if( !containerGroups[options.group]) { |
| 225 | + if(!containerGroups[options.group]) { |
225 | 226 | if(options.group === undefined) |
226 | 227 | options.group = groupCounter ++ |
| 228 | + |
227 | 229 | containerGroups[options.group] = new ContainerGroup(options) |
228 | 230 | } |
| 231 | + |
229 | 232 | return containerGroups[options.group] |
230 | 233 | } |
231 | 234 |
|
232 | 235 | ContainerGroup.prototype = { |
233 | 236 | dragInit: function (e, itemContainer) { |
234 | 237 | this.$document = $(itemContainer.el[0].ownerDocument) |
235 | 238 |
|
236 | | - if(itemContainer.enabled()){ |
237 | | - // get item to drag |
238 | | - this.item = $(e.target).closest(this.options.itemSelector) |
239 | | - this.itemContainer = itemContainer |
| 239 | + // get item to drag |
| 240 | + this.item = $(e.target).closest(this.options.itemSelector) |
| 241 | + this.itemContainer = itemContainer |
240 | 242 |
|
241 | | - if(this.item.is(this.options.exclude) || |
242 | | - !this.options.onMousedown(this.item, groupDefaults.onMousedown, e)){ |
243 | | - return |
244 | | - } |
245 | | - |
246 | | - this.setPointer(e) |
247 | | - this.toggleListeners('on') |
248 | | - } else { |
249 | | - this.toggleListeners('on', ['drop']) |
| 243 | + if(this.item.is(this.options.exclude) || |
| 244 | + !this.options.onMousedown(this.item, groupDefaults.onMousedown, e)){ |
| 245 | + return |
250 | 246 | } |
251 | 247 |
|
| 248 | + this.setPointer(e) |
| 249 | + this.toggleListeners('on') |
| 250 | + |
252 | 251 | this.setupDelayTimer() |
253 | 252 | this.dragInitDone = true |
254 | 253 | }, |
|
353 | 352 | var i = this.containers.length - 1, |
354 | 353 | offsetParent = this.containers[i].getItemOffsetParent() |
355 | 354 |
|
356 | | - if(!this.options.parentContainer){ |
| 355 | + if(!this.options.rootGroup){ |
357 | 356 | while(i--){ |
358 | 357 | if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){ |
359 | 358 | // If every container has the same offset parent, |
|
411 | 410 | this.clearDimensions() |
412 | 411 | this.clearOffsetParent() // TODO is this needed? |
413 | 412 | }, |
414 | | - toggleListeners: function (method, events) { |
415 | | - var that = this |
416 | | - events = events || ['drag','drop','scroll'] |
| 413 | + toggleListeners: function (method) { |
| 414 | + var that = this, |
| 415 | + events = ['drag','drop','scroll'] |
417 | 416 |
|
418 | 417 | $.each(events,function (i,event) { |
419 | 418 | that.$document[method](eventNames[event], that[event + 'Proxy']) |
|
424 | 423 | }, |
425 | 424 | // Recursively clear container and item dimensions |
426 | 425 | clearDimensions: function () { |
427 | | - this.containerDimensions = undefined |
| 426 | + this.traverse(function(object){ |
| 427 | + object._clearDimensions() |
| 428 | + }) |
| 429 | + }, |
| 430 | + traverse: function(callback) { |
| 431 | + callback(this) |
428 | 432 | var i = this.containers.length |
429 | 433 | while(i--){ |
430 | | - this.containers[i].clearDimensions() |
| 434 | + this.containers[i].traverse(callback) |
431 | 435 | } |
432 | 436 | }, |
433 | | - destroy: function () { |
434 | | - // TODO iterate over subgroups and destroy them |
435 | | - // TODO remove all events |
| 437 | + _clearDimensions: function(){ |
| 438 | + this.containerDimensions = undefined |
| 439 | + }, |
| 440 | + _destroy: function () { |
436 | 441 | containerGroups[this.options.group] = undefined |
437 | 442 | } |
438 | 443 | } |
|
443 | 448 |
|
444 | 449 | this.group = ContainerGroup.get(this.options) |
445 | 450 | this.rootGroup = this.options.rootGroup || this.group |
446 | | - this.parentContainer = this.options.parentContainer |
447 | 451 | this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector |
448 | 452 |
|
449 | | - var itemPath = this.rootGroup.options.itemPath, |
450 | | - target = itemPath ? this.el.find(itemPath) : this.el |
| 453 | + var itemPath = this.rootGroup.options.itemPath |
| 454 | + this.target = itemPath ? this.el.find(itemPath) : this.el |
451 | 455 |
|
452 | | - target.on(eventNames.start, this.handle, $.proxy(this.dragInit, this)) |
| 456 | + this.target.on(eventNames.start, this.handle, $.proxy(this.dragInit, this)) |
453 | 457 |
|
454 | 458 | if(this.options.drop) |
455 | 459 | this.group.containers.push(this) |
|
459 | 463 | dragInit: function (e) { |
460 | 464 | var rootGroup = this.rootGroup |
461 | 465 |
|
462 | | - if( !rootGroup.dragInitDone && |
| 466 | + if( !this.disabled && |
| 467 | + !rootGroup.dragInitDone && |
463 | 468 | this.options.drag && |
464 | 469 | this.isValidDrag(e)) { |
465 | 470 | rootGroup.dragInit(e, this) |
|
479 | 484 | rootGroup.options.isValidTarget(rootGroup.item, this) |
480 | 485 |
|
481 | 486 | if(!i && validTarget){ |
482 | | - var itemPath = this.rootGroup.options.itemPath, |
483 | | - target = itemPath ? this.el.find(itemPath) : this.el |
484 | | - |
485 | | - rootGroup.movePlaceholder(this, target, "append") |
| 487 | + rootGroup.movePlaceholder(this, this.target, "append") |
486 | 488 | return true |
487 | 489 | } else |
488 | 490 | while(i--){ |
|
555 | 557 | return this.options.nested && this.getContainerGroup(index) |
556 | 558 | }, |
557 | 559 | getContainerGroup: function (index) { |
558 | | - var childGroup = $.data(this.items[index], "subContainer") |
| 560 | + var childGroup = $.data(this.items[index], subContainerKey) |
559 | 561 | if( childGroup === undefined){ |
560 | 562 | var childContainers = this.$getChildren(this.items[index], "container") |
561 | 563 | childGroup = false |
562 | 564 |
|
563 | 565 | if(childContainers[0]){ |
564 | 566 | var options = $.extend({}, this.options, { |
565 | | - parentContainer: this, |
566 | 567 | rootGroup: this.rootGroup, |
567 | 568 | group: groupCounter ++ |
568 | 569 | }) |
569 | 570 | childGroup = childContainers[pluginName](options).data(pluginName).group |
570 | 571 | } |
571 | | - $.data(this.items[index], "subContainer", childGroup) |
| 572 | + $.data(this.items[index], subContainerKey, childGroup) |
572 | 573 | } |
573 | 574 | return childGroup |
574 | 575 | }, |
575 | | - enabled: function () { |
576 | | - return !this.disabled && (!this.parentContainer || this.parentContainer.enabled()) |
577 | | - }, |
578 | 576 | $getChildren: function (parent, type) { |
579 | 577 | var options = this.rootGroup.options, |
580 | 578 | path = options[type + "Path"], |
|
596 | 594 |
|
597 | 595 | return this.rootGroup.options.serialize(parent, children, isContainer) |
598 | 596 | }, |
599 | | - clearDimensions: function () { |
| 597 | + traverse: function(callback) { |
| 598 | + $.each(this.items || [], function(item){ |
| 599 | + var group = $.data(this, subContainerKey) |
| 600 | + if(group) |
| 601 | + group.traverse(callback) |
| 602 | + }); |
| 603 | + |
| 604 | + callback(this) |
| 605 | + }, |
| 606 | + _clearDimensions: function () { |
600 | 607 | this.itemDimensions = undefined |
601 | | - if(this.items && this.items[0]){ |
602 | | - var i = this.items.length |
603 | | - while(i--){ |
604 | | - var group = $.data(this.items[i], "subContainer") |
605 | | - if(group) |
606 | | - group.clearDimensions() |
607 | | - } |
608 | | - } |
| 608 | + }, |
| 609 | + _destroy: function() { |
| 610 | + var that = this; |
| 611 | + |
| 612 | + this.target.off(eventNames.start, this.handle); |
| 613 | + this.el.removeData(pluginName) |
| 614 | + |
| 615 | + if(this.options.drop) |
| 616 | + this.group.containers = $.grep(this.group.containers, function(val){ |
| 617 | + return val != that |
| 618 | + }) |
| 619 | + |
| 620 | + $.each(this.items || [], function(){ |
| 621 | + $.removeData(this, subContainerKey) |
| 622 | + }) |
609 | 623 | } |
610 | 624 | } |
611 | 625 |
|
612 | 626 | var API = { |
613 | | - enable: function (ignoreChildren) { |
614 | | - this.disabled = false |
| 627 | + enable: function() { |
| 628 | + this.traverse(function(object){ |
| 629 | + object.disabled = false |
| 630 | + }) |
615 | 631 | }, |
616 | | - disable: function (ignoreChildren) { |
617 | | - this.disabled = true |
| 632 | + disable: function (){ |
| 633 | + this.traverse(function(object){ |
| 634 | + object.disabled = true |
| 635 | + }) |
618 | 636 | }, |
619 | 637 | serialize: function () { |
620 | 638 | return this._serialize(this.el, true) |
621 | 639 | }, |
622 | 640 | refresh: function() { |
623 | | - this.clearDimensions() |
| 641 | + this.traverse(function(object){ |
| 642 | + object._clearDimensions() |
| 643 | + }) |
624 | 644 | }, |
625 | 645 | destroy: function () { |
626 | | - this.rootGroup.destroy() |
| 646 | + this.traverse(function(object){ |
| 647 | + object._destroy(); |
| 648 | + }) |
627 | 649 | } |
628 | 650 | } |
629 | 651 |
|
|
0 commit comments