Changeset 5320
- Timestamp:
- 04/25/08 11:26:10 (9 months ago)
- Location:
- trunk/plugins/treeview
- Files:
-
- 2 modified
-
demo/sortable.html (modified) (6 diffs)
-
jquery.treeview.sortable.js (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/plugins/treeview/demo/sortable.html
r5301 r5320 29 29 .drop { 30 30 background-color: #eee !important; 31 outline: 1px solid black;31 border: 1px dotted #333; 32 32 } 33 33 .bar { 34 34 border-bottom: 1px dotted blue; 35 35 } 36 37 .float { 38 float: left; 39 border: 1px solid #aaa; 40 margin: 10px; 41 padding: 10px; 42 } 43 44 div.treeview-helper { 45 border: 1px solid #aaa; 46 background: #fff; 47 padding: 5px; 48 padding-left: 25px; 49 } 50 36 51 </style> 37 52 … … 59 74 60 75 61 $(function() { 62 63 $("#browser").treeview().sortable({ 76 77 78 $.fn.sortableTreeview = function(o) { 79 this.each(function() { 80 81 $(this).treeview().sortable({ 82 connectWith: o.connectWith, 64 83 items: 'li', 84 helper: function(e,item) { 85 return $("<div class='treeview-helper'>"+item.find("span").html()+"</div>"); 86 }, 65 87 //revert: true, 66 88 sortIndication: { … … 76 98 }, 77 99 start: function(event, ui) { 78 $("#browser").treeview({update: ui.item});100 ui.instance.element.treeview({update: ui.item}); 79 101 80 102 }, 81 103 update: function(event, ui) { 82 104 ui.item.removeClass(); 83 $("#browser").treeview({add: ui.item});105 ui.instance.element.treeview({add: ui.item}); 84 106 } 85 107 }); 86 108 87 $(" #browser .folder").droppable({109 $(".folder", this).droppable({ 88 110 accept: "li", 89 111 hoverClass: "drop", 112 tolerance: "pointer", 90 113 drop: function(e,ui) { 91 114 $("> ul", this.parentNode).append(ui.draggable); … … 93 116 }); 94 117 118 }); 119 }; 120 121 122 $(function() { 123 124 125 $("#browser, #browser2").sortableTreeview({ connectWith: ["#browser", "#browser2"] }); 95 126 96 127 }) … … 108 139 <h4>Sample 1 - default, right-click to remove items</h4> 109 140 141 <div class="float"> 110 142 <ul id="browser" class="filetree"> 111 143 <li><span class="folder">Folder 1</span> … … 141 173 <li><span class="file">File 4</span></li> 142 174 </ul> 175 </div> 176 177 <div class="float"> 178 <ul id="browser2" class="filetree"> 179 <li><span class="folder">Folder 1</span> 180 <ul> 181 <li><span class="file">Item 1.1</span></li> 182 </ul> 183 </li> 184 <li><span class="folder">Folder 2</span> 185 <ul> 186 <li><span class="folder">Subfolder 2.1</span> 187 <ul id="folder21"> 188 <li><span class="file">File 2.1.1</span></li> 189 <li><span class="file">File 2.1.2</span></li> 190 <li><span class="file">File 2.1.3</span></li> 191 <li class="closed"><span class="folder">Folder 3 (closed at start)</span> 192 <ul> 193 <li><span class="file">File 3.1</span></li> 194 </ul> 195 </li> 196 <li><span class="file">File 2.1.4</span></li> 197 <li><span class="file">File 2.1.5</span></li> 198 <li><span class="file">File 2.1.6</span></li> 199 </ul> 200 </li> 201 <li><span class="file">File 2.2</span></li> 202 </ul> 203 </li> 204 <li class="closed"><span class="folder">Folder 3 (closed at start)</span> 205 <ul> 206 <li><span class="file">File 3.1</span></li> 207 </ul> 208 </li> 209 <li><span class="file">File 4</span></li> 210 </ul> 211 </div> 143 212 144 213 </div> -
trunk/plugins/treeview/jquery.treeview.sortable.js
r5301 r5320 162 162 /* Be careful with the following core functions */ 163 163 intersectsWith: function(item) { 164 165 var x1 = this.position.absolute.left , x2 = x1 + this.helperProportions.width,166 y1 = this.position.absolute.top , y2 = y1 + this.helperProportions.height;164 165 var x1 = this.position.absolute.left - 10, x2 = x1 + 10, 166 y1 = this.position.absolute.top - 10, y2 = y1 + 10; 167 167 var l = item.left, r = l + item.width, 168 168 t = item.top, b = t + item.height; … … 175 175 }, 176 176 intersectsWithEdge: function(item) { 177 var y1 = this.position.absolute.top , y2 = y1 + this.helperProportions.height;177 var y1 = this.position.absolute.top - 10, y2 = y1 + 10; 178 178 var t = item.top, b = t + item.height; 179 179 180 if(!this.intersectsWith(item.item.parents(".ui-sortable").data("sortable").containerCache)) return false; 180 181 181 182 if (!( t < y1 + (this.helperProportions.height / 2) // Bottom Half … … 292 293 //Create and append the visible helper 293 294 this.helper = typeof o.helper == 'function' ? $(o.helper.apply(this.element[0], [e, this.currentItem])) : this.currentItem.clone(); 294 if(!this.helper.parents('body').length) this.helper.appendTo( o.appendTo || this.currentItem[0].parentNode); //Add the helper to the DOM if that didn't happen already295 if(!this.helper.parents('body').length) this.helper.appendTo("body"); //Add the helper to the DOM if that didn't happen already 295 296 this.helper.css({ position: 'absolute', clear: 'both' }).addClass('ui-sortable-helper'); //Position it absolutely and add a helper class 296 297 … … 298 299 $.extend(this, { 299 300 offsetParent: this.helper.offsetParent(), 300 offsets: { 301 absolute: this.currentItem.offset() 302 }, 303 mouse: { 304 start: { top: e.pageY, left: e.pageX } 305 }, 306 margins: { 307 top: parseInt(this.currentItem.css("marginTop")) || 0, 308 left: parseInt(this.currentItem.css("marginLeft")) || 0 309 } 301 offsets: { absolute: this.currentItem.offset() } 310 302 }); 311 312 //The relative click offset313 this.offsets.parent = this.offsetParent.offset();314 this.clickOffset = { left: e.pageX - this.offsets.absolute.left, top: e.pageY - this.offsets.absolute.top };315 316 this.originalPosition = {317 left: this.offsets.absolute.left - this.offsets.parent.left - this.margins.left,318 top: this.offsets.absolute.top - this.offsets.parent.top - this.margins.top319 }320 321 //Generate a flexible offset that will later be subtracted from e.pageX/Y322 //I hate margins - they need to be removed before positioning the element absolutely..323 this.offset = {324 left: e.pageX - this.originalPosition.left,325 top: e.pageY - this.originalPosition.top326 };327 303 328 304 //Save the first time position 329 305 $.extend(this, { 330 306 position: { 331 current: { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left},332 absolute: { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top},307 current: { left: e.pageX, top: e.pageY }, 308 absolute: { left: e.pageX, top: e.pageY }, 333 309 dom: this.currentItem.prev()[0] 334 } 310 }, 311 clickOffset: { left: -5, top: -5 } 335 312 }); 336 313 … … 338 315 this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; //Save and store the helper proportions 339 316 340 //If we have something in cursorAt, we'll use it 341 if(o.cursorAt) { 342 if(o.cursorAt.top != undefined || o.cursorAt.bottom != undefined) { 343 this.offset.top -= this.clickOffset.top - (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom)); 344 this.clickOffset.top = (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom)); 345 } 346 if(o.cursorAt.left != undefined || o.cursorAt.right != undefined) { 347 this.offset.left -= this.clickOffset.left - (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right)); 348 this.clickOffset.left = (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right)); 349 } 350 } 351 352 353 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i].propagate("activate", e, this); } //Post 'activate' events to possible containers 317 for (var i = this.containers.length - 1; i >= 0; i--) { 318 this.containers[i].propagate("activate", e, this); 319 } //Post 'activate' events to possible containers 354 320 355 321 //Prepare possible droppables … … 363 329 stop: function(e) { 364 330 365 366 367 368 this.options.sortIndication.remove.call(this.currentItem, this.newPositionAt); //remove sort indicator 331 if(this.newPositionAt) this.options.sortIndication.remove.call(this.currentItem, this.newPositionAt); //remove sort indicator 369 332 this.propagate("stop", e); //Call plugins and trigger callbacks 370 333 … … 391 354 //If we are using droppables, inform the manager about the drop 392 355 var dropped = ($.ui.ddmanager && !this.options.dropBehaviour) ? $.ui.ddmanager.drop(this, e) : false; 393 if(!dropped ) this.newPositionAt[this.direction == 'down' ? 'before' : 'after'](this.currentItem); //Append to element to its new position356 if(!dropped && this.newPositionAt) this.newPositionAt[this.direction == 'down' ? 'before' : 'after'](this.currentItem); //Append to element to its new position 394 357 395 358 this.dragging = false; … … 403 366 404 367 //Compute the helpers position 405 this.position.current = { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left};406 this.position.absolute = { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top};368 this.position.current = { top: e.pageY + 5, left: e.pageX + 5 }; 369 this.position.absolute = { left: e.pageX + 5, top: e.pageY + 5 }; 407 370 408 371 //Interconnect with droppables … … 418 381 } else { 419 382 for (var i = this.items.length - 1; i >= 0; i--) { 383 384 if(this.currentItem[0].contains(this.items[i].item[0])) continue; 385 420 386 var intersection = this.intersectsWithEdge(this.items[i]); 421 387 if(!intersection) continue; … … 446 412 } 447 413 }); 448 449 /* 450 * Sortable Extensions 451 */ 452 453 $.ui.plugin.add("sortable", "cursor", { 454 start: function(e, ui) { 455 var t = $('body'); 456 if (t.css("cursor")) ui.options._cursor = t.css("cursor"); 457 t.css("cursor", ui.options.cursor); 458 }, 459 stop: function(e, ui) { 460 if (ui.options._cursor) $('body').css("cursor", ui.options._cursor); 461 } 462 }); 463 464 $.ui.plugin.add("sortable", "zIndex", { 465 start: function(e, ui) { 466 var t = ui.helper; 467 if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex"); 468 t.css('zIndex', ui.options.zIndex); 469 }, 470 stop: function(e, ui) { 471 if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex); 472 } 473 }); 474 475 $.ui.plugin.add("sortable", "opacity", { 476 start: function(e, ui) { 477 var t = ui.helper; 478 if(t.css("opacity")) ui.options._opacity = t.css("opacity"); 479 t.css('opacity', ui.options.opacity); 480 }, 481 stop: function(e, ui) { 482 if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity); 483 } 484 }); 485 486 487 $.ui.plugin.add("sortable", "revert", { 488 stop: function(e, ui) { 489 var self = ui.instance; 490 self.cancelHelperRemoval = true; 491 var cur = self.currentItem.offset(); 492 var op = self.helper.offsetParent().offset(); 493 if(ui.instance.options.zIndex) ui.helper.css('zIndex', ui.instance.options.zIndex); //Do the zIndex again because it already was resetted by the plugin above on stop 494 495 //Also animate the placeholder if we have one 496 if(ui.instance.placeholder) ui.instance.placeholder.animate({ opacity: 'hide' }, parseInt(ui.options.revert, 10) || 500); 497 498 499 ui.helper.animate({ 500 left: cur.left - op.left - self.margins.left, 501 top: cur.top - op.top - self.margins.top 502 }, parseInt(ui.options.revert, 10) || 500, function() { 503 self.currentItem.css('visibility', 'visible'); 504 window.setTimeout(function() { 505 if(self.placeholder) self.placeholder.remove(); 506 self.helper.remove(); 507 if(ui.options._zIndex) ui.helper.css('zIndex', ui.options._zIndex); 508 }, 50); 509 }); 510 } 511 }); 512 513 514 $.ui.plugin.add("sortable", "containment", { 515 start: function(e, ui) { 516 517 var o = ui.options; 518 if((o.containment.left != undefined || o.containment.constructor == Array) && !o._containment) return; 519 if(!o._containment) o._containment = o.containment; 520 521 if(o._containment == 'parent') o._containment = this[0].parentNode; 522 if(o._containment == 'sortable') o._containment = this[0]; 523 if(o._containment == 'document') { 524 o.containment = [ 525 0, 526 0, 527 $(document).width(), 528 ($(document).height() || document.body.parentNode.scrollHeight) 529 ]; 530 } else { //I'm a node, so compute top/left/right/bottom 531 532 var ce = $(o._containment); 533 var co = ce.offset(); 534 535 o.containment = [ 536 co.left, 537 co.top, 538 co.left+(ce.outerWidth() || ce[0].scrollWidth), 539 co.top+(ce.outerHeight() || ce[0].scrollHeight) 540 ]; 541 } 542 543 }, 544 sort: function(e, ui) { 545 546 var o = ui.options; 547 var h = ui.helper; 548 var c = o.containment; 549 var self = ui.instance; 550 var borderLeft = (parseInt(self.offsetParent.css("borderLeftWidth"), 10) || 0); 551 var borderRight = (parseInt(self.offsetParent.css("borderRightWidth"), 10) || 0); 552 var borderTop = (parseInt(self.offsetParent.css("borderTopWidth"), 10) || 0); 553 var borderBottom = (parseInt(self.offsetParent.css("borderBottomWidth"), 10) || 0); 554 555 if(c.constructor == Array) { 556 if((self.position.absolute.left < c[0])) self.position.current.left = c[0] - self.offsets.parent.left - self.margins.left; 557 if((self.position.absolute.top < c[1])) self.position.current.top = c[1] - self.offsets.parent.top - self.margins.top; 558 if(self.position.absolute.left - c[2] + self.helperProportions.width >= 0) self.position.current.left = c[2] - self.offsets.parent.left - self.helperProportions.width - self.margins.left - borderLeft - borderRight; 559 if(self.position.absolute.top - c[3] + self.helperProportions.height >= 0) self.position.current.top = c[3] - self.offsets.parent.top - self.helperProportions.height - self.margins.top - borderTop - borderBottom; 560 } else { 561 if((ui.position.left < c.left)) self.position.current.left = c.left; 562 if((ui.position.top < c.top)) self.position.current.top = c.top; 563 if(ui.position.left - self.offsetParent.innerWidth() + self.helperProportions.width + c.right + borderLeft + borderRight >= 0) self.position.current.left = self.offsetParent.innerWidth() - self.helperProportions.width - c.right - borderLeft - borderRight; 564 if(ui.position.top - self.offsetParent.innerHeight() + self.helperProportions.height + c.bottom + borderTop + borderBottom >= 0) self.position.current.top = self.offsetParent.innerHeight() - self.helperProportions.height - c.bottom - borderTop - borderBottom; 565 } 566 567 } 568 }); 569 570 $.ui.plugin.add("sortable", "axis", { 571 sort: function(e, ui) { 572 var o = ui.options; 573 if(o.constraint) o.axis = o.constraint; //Legacy check 574 o.axis == 'x' ? ui.instance.position.top = ui.instance.originalPosition.top : ui.instance.position.left = ui.instance.originalPosition.left; 575 } 576 }); 577 578 $.ui.plugin.add("sortable", "scroll", { 579 start: function(e, ui) { 580 var o = ui.options; 581 o.scrollSensitivity = o.scrollSensitivity || 20; 582 o.scrollSpeed = o.scrollSpeed || 20; 583 584 ui.instance.overflowY = function(el) { 585 do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode); 586 return $(document); 587 }(this); 588 ui.instance.overflowX = function(el) { 589 do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode); 590 return $(document); 591 }(this); 592 593 if(ui.instance.overflowY[0] != document && ui.instance.overflowY[0].tagName != 'HTML') ui.instance.overflowYstart = ui.instance.overflowY[0].scrollTop; 594 if(ui.instance.overflowX[0] != document && ui.instance.overflowX[0].tagName != 'HTML') ui.instance.overflowXstart = ui.instance.overflowX[0].scrollLeft; 595 596 }, 597 sort: function(e, ui) { 598 599 var o = ui.options; 600 var i = ui.instance; 601 602 if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') { 603 if(i.overflowY[0].offsetHeight - (ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity) 604 i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed; 605 if((ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity) 606 i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed; 607 } else { 608 //$(document.body).append('<p>'+(e.pageY - $(document).scrollTop())+'</p>'); 609 if(e.pageY - $(document).scrollTop() < o.scrollSensitivity) 610 $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 611 if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity) 612 $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 613 } 614 615 if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') { 616 if(i.overflowX[0].offsetWidth - (ui.position.left - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity) 617 i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed; 618 if((ui.position.top - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity) 619 i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed; 620 } else { 621 if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity) 622 $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 623 if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 624 $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 625 } 626 627 //ui.instance.recallOffset(e); 628 i.offset = { 629 left: i.mouse.start.left - i.originalPosition.left + (i.overflowXstart !== undefined ? i.overflowXstart - i.overflowX[0].scrollLeft : 0), 630 top: i.mouse.start.top - i.originalPosition.top + (i.overflowYstart !== undefined ? i.overflowYstart - i.overflowX[0].scrollTop : 0) 631 }; 632 633 } 634 }); 414 415 635 416 636 417 })(jQuery);
