1.6: droppables can now operate in a seperate scope, droppables and sortables in the current dragged item are filtered out at start, preventing node hierarchy issues
<script type="text/javascript" src="../../ui/ui.droppable.js"></script>\r
<script type="text/javascript" src="../../ui/ui.resizable.js"></script>\r
<script type="text/javascript" src="../../ui/ui.sortable.js"></script>\r
+<script type="text/javascript" src="../../../branches/1.8/ui.tree.js"></script>\r
\r
\r
<script>\r
$(document).ready(function(){\r
\r
-\r
-$.widget("ui.tree", {\r
- init: function() {\r
-\r
- var self = this;\r
-\r
- this.element.sortable({\r
- items: this.options.sortOn,\r
- placeholder: "ui-tree-placeholder",\r
- start: function() {\r
- $(this).data("sortable").placeholder.hide();\r
- $(this).data("sortable").refreshPositions(true); \r
- },\r
- stop: function() {\r
- var self = $(this).data("sortable");\r
- $(self.options.items, self.element).css("border-top", "0").css("border-bottom", "0");\r
- },\r
- sortIndicator: function(e, item, append, hardRefresh) {\r
- \r
- append ? append[0].appendChild(this.placeholder[0]) : item.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? item.item[0] : item.item[0].nextSibling));\r
- \r
- $(this.options.items, this.element).css("border-top", "0").css("border-bottom", "0");\r
- item.item.css("border-"+(this.direction == "down" ? "top" : "bottom"), "2px solid black");\r
- \r
- }\r
- });\r
- \r
- \r
- \r
- //Make certain nodes droppable\r
- $(this.options.dropOn, this.element).droppable({\r
- accept: this.options.sortOn,\r
- hoverClass: this.options.hoverClass,\r
- //tolerance: "pointer",\r
- over: function() {\r
- $(self.options.sortOn, self.element).css("border-top", "0").css("border-bottom", "0");\r
- },\r
- drop: function(e, ui) {\r
- $(this).parent().find("ul").append(ui.draggable);\r
- self.element.data("sortable")._noFinalSort = true;\r
- }\r
- });\r
-\r
- }\r
-});\r
-\r
-$.extend($.ui.tree, {\r
- defaults: {\r
- sortOn: "*",\r
- dropOn: "div",\r
- hoverClass: "ui-tree-hover"\r
- }\r
-});\r
-\r
$("ul.sortable").tree({\r
sortOn: "li",\r
- dropOn: "div",\r
- hoverClass: "hover"\r
+ dropOn: ".folder",\r
+ dropHoverClass: "hover"\r
});\r
\r
\r
.placeholder {\r
display: none;\r
}\r
+\r
+.hover-up {\r
+ border-bottom: 2px solid black;\r
+}\r
+\r
+.hover-down {\r
+ border-top: 2px solid black;\r
+}\r
+\r
+.folder {\r
+ border: 1px solid black;\r
+}\r
+\r
+li {\r
+ padding: 3px;\r
+}\r
+\r
</style>\r
</head>\r
\r
<body>\r
\r
<ul class="sortable">\r
- <li>Item 1</li>\r
- <li><div>Item 2</div>\r
+ <li><div class="folder">Item 1</div></li>\r
+ <li><div class="folder">Item 2</div>\r
<ul>\r
<li>Sub Item 1</li>\r
<li>Sub Item 3</li>\r
<li>Sub Item 5</li>\r
</ul>\r
</li>\r
- <li>Item 3</li>\r
- <li>Item 4</li>\r
- <li><div>Item 2</div>\r
+ <li><div class="folder">Item 3</div></li>\r
+ <li><div class="folder">Item 4</div></li>\r
+ <li><div class="folder">Item 4</div></li>\r
+ <li><div class="folder">Item 4</div></li>\r
+ <li><div class="folder">Item 4</div></li>\r
+ <li><div class="folder">Item 4</div></li>\r
+ <li><div class="folder">Item 4</div></li>\r
+ <li><div class="folder">Item 4</div></li>\r
+ <li><div class="folder">Item 2</div>\r
<ul>\r
<li>Sub Item 1</li>\r
<li>Sub Item 3</li>\r
cancel: ":input",
delay: 0,
distance: 1,
- helper: "original"
+ helper: "original",
+ scope: "default"
}
});
this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
// Add the reference and positions to the manager
- $.ui.ddmanager.droppables.push(this);
+ $.ui.ddmanager.droppables[this.options.scope] = $.ui.ddmanager.droppables[this.options.scope] || [];
+ $.ui.ddmanager.droppables[this.options.scope].push(this);
},
plugins: {},
};
},
destroy: function() {
- var drop = $.ui.ddmanager.droppables;
+ var drop = $.ui.ddmanager.droppables[this.options.scope];
for ( var i = 0; i < drop.length; i++ )
if ( drop[i] == this )
drop.splice(i, 1);
$.extend($.ui.droppable, {
defaults: {
disabled: false,
- tolerance: 'intersect'
+ tolerance: 'intersect',
+ scope: 'default'
}
});
*/
$.ui.ddmanager = {
current: null,
- droppables: [],
+ droppables: { scope: [] },
prepareOffsets: function(t, e) {
- var m = $.ui.ddmanager.droppables;
+ var m = $.ui.ddmanager.droppables[t.options.scope];
var type = e ? e.type : null; // workaround for #2317
+ var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
- for (var i = 0; i < m.length; i++) {
- if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element,(t.currentItem || t.element)))) continue;
- m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
+ droppablesLoop: for (var i = 0; i < m.length; i++) {
+
+ if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element,(t.currentItem || t.element)))) continue; //No disabled and non-accepted
+ for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
+ m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
+
m[i].offset = m[i].element.offset();
m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
- if(type == "dragstart" || type == "sortactivate") m[i].activate.call(m[i], e); //Activate the droppable if used directly from draggables
+ if(type == "dragstart" || type == "sortactivate") m[i].activate.call(m[i], e); //Activate the droppable if used directly from draggables
+
}
},
drop: function(draggable, e) {
var dropped = false;
- $.each($.ui.ddmanager.droppables, function() {
+ $.each($.ui.ddmanager.droppables[draggable.options.scope], function() {
if(!this.options) return;
if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
//Run through all droppables and check their positions based on specific tolerance options
- $.each($.ui.ddmanager.droppables, function() {
+ $.each($.ui.ddmanager.droppables[draggable.options.scope], function() {
if(this.options.disabled || this.greedyChild || !this.visible) return;
var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
if ((x1 + dxClick) > l && (x1 + dxClick) < l + item.width/2) return 2;
if ((x1 + dxClick) > l + item.width/2 && (x1 + dxClick) < r) return 1;
} else {
- var height = item.height, helperHeight = this.helperProportions.height;
+ var height = item.height;
var direction = y1 - this.updateOriginalPosition.top < 0 ? 2 : 1; // 2 = up
if (direction == 1 && (y1 + dyClick) < t + height/2) { return 2; } // up
},
+ removeCurrentsFromItems: function() {
+
+ var list = this.currentItem.find(":data(sortable-item)");
+
+ for (var i=0; i < this.items.length; i++) {
+
+ for (var j=0; j < list.length; j++) {
+ if(list[j] == this.items[i].item[0])
+ this.items.splice(i,1);
+ };
+
+ };
+
+ },
+
refreshItems: function() {
this.items = [];
}
this.currentItem = currentItem;
+ this.removeCurrentsFromItems();
return true;
},
//Call plugins and callbacks
this.propagate("start", e);
- this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Recache the helper size
+ if(!this._preserveHelperProportions) this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Recache the helper size
if(o.cursorAt) {
if(o.cursorAt.left != undefined) this.offset.click.left = o.cursorAt.left;
zIndex: 1000,
dropOnEmpty: true,
appendTo: "parent",
- sortIndicator: $.ui.sortable.prototype.rearrange
+ sortIndicator: $.ui.sortable.prototype.rearrange,
+ scope: "default"
}
});