Skip to content

Commit f048a8c

Browse files
committed
Update pages. See main branch for changes
1 parent a68e193 commit f048a8c

File tree

7 files changed

+371
-212
lines changed

7 files changed

+371
-212
lines changed

css/jquery-sortable.css

Lines changed: 105 additions & 105 deletions
Large diffs are not rendered by default.

index.html

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
<li>
3535
<a href='#nested'>Toggable nested lists</a>
3636
</li>
37+
<li>
38+
<a href='#limited-target'>Limited drop targets</a>
39+
</li>
3740
<li>
3841
<a href='#bootstrap'>Sorting a bootstrap menu</a>
3942
</li>
@@ -68,15 +71,15 @@ <h1>jQuery Sortable</h1>
6871
<a class='btn btn-large btn-success' href='js/jquery-sortable.js'>
6972
<i class='icon-hdd icon-white'></i>
7073
Download
71-
(v0.9.6)
74+
(v0.9.7)
7275
</a>
7376
</p>
7477
<p>
7578
<small>
7679
Download
7780
<a href='js/jquery-sortable-min.js'>minified</a>
7881
version
79-
(7.3 kb)
82+
(7.7 kb)
8083
</small>
8184
</p>
8285
</div>
@@ -158,8 +161,14 @@ <h3>
158161
Only list items that contain a sublist are drop targets.
159162
</p>
160163
<ol class='default vertical'>
161-
<li>First</li>
162-
<li>Second</li>
164+
<li>
165+
First
166+
<ol></ol>
167+
</li>
168+
<li>
169+
Second
170+
<ol></ol>
171+
</li>
163172
<li>
164173
Third
165174
<ol>
@@ -527,6 +536,55 @@ <h2>Toggable nested lists</h2>
527536
</li>
528537
</ol>
529538
</div>
539+
</div>
540+
</div>
541+
<div id='limited-target'>
542+
<h2>Connected lists with limited drop targets</h2>
543+
<div class='row'>
544+
<div class="span12 example">
545+
<div class="CodeRay">
546+
<div class="code"><pre><span class="predefined">$</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">ol.limited_drop_targets</span><span class="delimiter">&quot;</span></span>).sortable({
547+
<span class="key">group</span>: <span class="string"><span class="delimiter">'</span><span class="content">limited_drop_targets</span><span class="delimiter">'</span></span>,
548+
<span class="function">isValidTarget</span>: <span class="keyword">function</span> (item, container) {
549+
<span class="keyword">if</span>(item.is(<span class="string"><span class="delimiter">&quot;</span><span class="content">.highlight</span><span class="delimiter">&quot;</span></span>))
550+
<span class="keyword">return</span> <span class="predefined-constant">true</span>
551+
<span class="keyword">else</span> {
552+
<span class="keyword">return</span> item.parent(<span class="string"><span class="delimiter">&quot;</span><span class="content">ol</span><span class="delimiter">&quot;</span></span>)[<span class="integer">0</span>] == container.el[<span class="integer">0</span>]
553+
}
554+
}
555+
})</pre></div>
556+
</div>
557+
558+
</div>
559+
<div class='span4'>
560+
<ul>
561+
<li>
562+
<strong>Limit the drop targets</strong>
563+
of the dragged item
564+
</li>
565+
</ul>
566+
<p><div class="btn btn-primary show-code" data-toggle="button"><i class="icon-chevron-down"></i> show me the code</div></p>
567+
</div>
568+
<div class='span4'>
569+
<ol class='limited_drop_targets vertical'>
570+
<li class='highlight'>Item 1</li>
571+
<li>Item 2</li>
572+
<li class='highlight'>Item 3</li>
573+
<li>Item 4</li>
574+
<li class='highlight'>Item 5</li>
575+
<li>Item 6</li>
576+
</ol>
577+
</div>
578+
<div class='span4'>
579+
<ol class='limited_drop_targets vertical'>
580+
<li>Item 1</li>
581+
<li>Item 2</li>
582+
<li>Item 3</li>
583+
<li class='highlight'>Item 4</li>
584+
<li class='highlight'>Item 5</li>
585+
<li class='highlight'>Item 6</li>
586+
</ol>
587+
</div>
530588
</div>
531589
</div>
532590
<div id='bootstrap'>
@@ -880,6 +938,18 @@ <h2 id='group-options'>Group options</h2>
880938

881939
</td>
882940
<td> The css selector of the items</td>
941+
</tr><tr><td>
942+
<code>isValidTarget</code>
943+
</td>
944+
<td>
945+
<div class="CodeRay">
946+
<div class="code"><pre><span class="keyword">function</span> (item, container) {
947+
<span class="keyword">return</span> <span class="predefined-constant">true</span>
948+
}</pre></div>
949+
</div>
950+
951+
</td>
952+
<td> Check if the dragged item may be inside the container. Use with care, since the search for a valid container entails a depth first search and may be quite expensive.</td>
883953
</tr><tr><td>
884954
<code>onDrag</code>
885955
</td>

js/application.js

Lines changed: 87 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ colors = jQuery.Color.names = {
10821082

10831083
}(window.jQuery);
10841084
/* ===================================================
1085-
* jquery-sortable.js v0.9.6
1085+
* jquery-sortable.js v0.9.7
10861086
* http://johnny.github.com/jquery-sortable/
10871087
* ===================================================
10881088
* Copyright (c) 2012 Jonas von Andrian
@@ -1114,8 +1114,6 @@ colors = jQuery.Color.names = {
11141114
!function ( $, window, undefined){
11151115
var eventNames,
11161116
pluginName = 'sortable',
1117-
document = window.document,
1118-
$document = $(document),
11191117
containerDefaults = {
11201118
// If true, items can be dragged from this container
11211119
drag: true,
@@ -1139,6 +1137,12 @@ colors = jQuery.Color.names = {
11391137
handle: "",
11401138
// The css selector of the items
11411139
itemSelector: "li",
1140+
// Check if the dragged item may be inside the container.
1141+
// Use with care, since the search for a valid container entails a depth first search
1142+
// and may be quite expensive.
1143+
isValidTarget: function (item, container) {
1144+
return true
1145+
},
11421146
// Executed at the beginning of a mouse move event.
11431147
// The Placeholder has not been moved yet
11441148
onDrag: function (item, position, _super) {
@@ -1226,7 +1230,7 @@ colors = jQuery.Color.names = {
12261230
}
12271231
}
12281232

1229-
function getNearest(dimensions, pointer, lastPointer) {
1233+
function sortByDistanceDesc(dimensions, pointer, lastPointer) {
12301234
pointer = [pointer.left, pointer.top]
12311235
lastPointer = lastPointer && [lastPointer.left, lastPointer.top]
12321236

@@ -1239,10 +1243,11 @@ colors = jQuery.Color.names = {
12391243
distances[i] = [i,d(dim,pointer), lastPointer && d(dim, lastPointer)]
12401244
}
12411245
distances = distances.sort(function (a,b) {
1242-
return a[1] - b[1] || a[2] - b[2] || a[0] - b[0]
1246+
return b[1] - a[1] || b[2] - a[2] || b[0] - a[0]
12431247
})
12441248

1245-
return distances[0]
1249+
// last entry is the closest
1250+
return distances
12461251
}
12471252

12481253
function processChildContainers(item, containerSelector, method, ignoreChildren) {
@@ -1265,10 +1270,14 @@ colors = jQuery.Color.names = {
12651270
this.scrolledProxy = $.proxy(this.scrolled, this)
12661271
this.dragProxy = $.proxy(this.drag, this)
12671272
this.dropProxy = $.proxy(this.drop, this)
1273+
12681274
if(this.options.parentGroup)
12691275
this.options.parentGroup.childGroups.push(this)
1270-
else
1276+
else {
12711277
this.placeholder = $(this.options.placeholder)
1278+
if(!options.isValidTarget)
1279+
this.options.isValidTarget = undefined
1280+
}
12721281
}
12731282

12741283
ContainerGroup.get = function (options) {
@@ -1282,9 +1291,9 @@ colors = jQuery.Color.names = {
12821291

12831292
ContainerGroup.prototype = {
12841293
dragInit: function (e, itemContainer) {
1285-
$document.on(eventNames.move + "." + pluginName, this.dragProxy)
1286-
$document.on(eventNames.end + "." + pluginName, this.dropProxy)
1287-
$document.on("scroll." + pluginName, this.scrolledProxy)
1294+
this.$document = $(itemContainer.el[0].ownerDocument)
1295+
1296+
this.toggleListeners('on')
12881297

12891298
// get item to drag
12901299
this.item = $(e.target).closest(this.options.itemSelector)
@@ -1299,6 +1308,7 @@ colors = jQuery.Color.names = {
12991308
processChildContainers(this.item, this.options.containerSelector, "disable", true)
13001309

13011310
this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart)
1311+
this.item.before(this.placeholder)
13021312
this.dragging = true
13031313
}
13041314

@@ -1314,14 +1324,11 @@ colors = jQuery.Color.names = {
13141324
y = e.pageY,
13151325
box = this.sameResultBox
13161326
if(!box || box.top > y || box.bottom < y || box.left > x || box.right < x)
1317-
this.processMove()
1327+
this.searchValidTarget()
13181328
},
13191329
drop: function (e) {
13201330
e.preventDefault()
1321-
1322-
$document.off(eventNames.move + "." + pluginName)
1323-
$document.off(eventNames.end + "." + pluginName)
1324-
$document.off("scroll." + pluginName)
1331+
this.toggleListeners('off')
13251332

13261333
if(!this.dragging)
13271334
return;
@@ -1336,26 +1343,33 @@ colors = jQuery.Color.names = {
13361343
this.lastAppendedItem = this.sameResultBox = undefined
13371344
this.dragging = false
13381345
},
1339-
processMove: function (pointer, lastPointer) {
1346+
searchValidTarget: function (pointer, lastPointer) {
13401347
if(!pointer){
13411348
pointer = this.relativePointer || this.pointer
13421349
lastPointer = this.lastRelativePointer || this.lastPointer
13431350
}
13441351

1345-
var nearest = getNearest(this.getContainerDimensions(),
1346-
pointer,
1347-
lastPointer)
1348-
1349-
if(nearest && (!nearest[1] || this.options.pullPlaceholder)){
1350-
var index = nearest[0],
1351-
container = this.containers[index]
1352-
if(!this.getOffsetParent()){
1353-
var offsetParent = container.getItemOffsetParent()
1354-
pointer = getRelativePosition(pointer, offsetParent)
1355-
lastPointer = getRelativePosition(lastPointer, offsetParent)
1352+
var distances = sortByDistanceDesc(this.getContainerDimensions(),
1353+
pointer,
1354+
lastPointer),
1355+
i = distances.length
1356+
1357+
while(i--){
1358+
var index = distances[i][0],
1359+
distance = distances[i][1]
1360+
1361+
if(!distance || this.options.pullPlaceholder){
1362+
var container = this.containers[index]
1363+
if(!this.getOffsetParent()){
1364+
var offsetParent = container.getItemOffsetParent()
1365+
pointer = getRelativePosition(pointer, offsetParent)
1366+
lastPointer = getRelativePosition(lastPointer, offsetParent)
1367+
}
1368+
if(container.searchValidTarget(pointer, lastPointer))
1369+
return true
13561370
}
1357-
container.processMove(pointer, lastPointer)
13581371
}
1372+
13591373
},
13601374
movePlaceholder: function (container, item, method, sameResultBox) {
13611375
var lastAppendedItem = this.lastAppendedItem
@@ -1430,6 +1444,11 @@ colors = jQuery.Color.names = {
14301444
this.clearDimensions()
14311445
this.clearOffsetParent()
14321446
},
1447+
toggleListeners: function (method) {
1448+
this.$document[method](eventNames.move + "." + pluginName, this.dragProxy)
1449+
[method](eventNames.end + "." + pluginName, this.dropProxy)
1450+
[method]("scroll." + pluginName, this.scrolledProxy)
1451+
},
14331452
// Recursively clear container and item dimensions
14341453
clearDimensions: function () {
14351454
this.containerDimensions = undefined
@@ -1479,22 +1498,32 @@ colors = jQuery.Color.names = {
14791498
rootGroup.placeholder.before(item).detach()
14801499
rootGroup.options.onDrop(item, this, groupDefaults.onDrop)
14811500
},
1482-
processMove: function (pointer, lastPointer) {
1483-
// get Element right below the pointer
1484-
var nearest = getNearest(this.getItemDimensions(),
1485-
pointer,
1486-
lastPointer),
1487-
rootGroup = this.rootGroup
1488-
if(!nearest)
1501+
searchValidTarget: function (pointer, lastPointer) {
1502+
var distances = sortByDistanceDesc(this.getItemDimensions(),
1503+
pointer,
1504+
lastPointer),
1505+
i = distances.length,
1506+
rootGroup = this.rootGroup,
1507+
validTarget = !rootGroup.options.isValidTarget ||
1508+
rootGroup.options.isValidTarget(rootGroup.item, this)
1509+
1510+
if(!i && validTarget){
14891511
rootGroup.movePlaceholder(this, this.el, "append")
1490-
else {
1491-
var index = nearest[0],
1492-
distance = nearest[1]
1493-
if(!distance && this.options.nested && this.getContainerGroup(index))
1494-
this.getContainerGroup(index).processMove(pointer, lastPointer)
1495-
else
1496-
this.movePlaceholder(index, pointer)
1497-
}
1512+
return true
1513+
} else
1514+
while(i--){
1515+
var index = distances[i][0],
1516+
distance = distances[i][1]
1517+
if(!distance && this.options.nested && this.getContainerGroup(index)){
1518+
var found = this.getContainerGroup(index).searchValidTarget(pointer, lastPointer)
1519+
if(found)
1520+
return true
1521+
}
1522+
else if(validTarget){
1523+
this.movePlaceholder(index, pointer)
1524+
return true
1525+
}
1526+
}
14981527
},
14991528
movePlaceholder: function (index, pointer) {
15001529
var item = $(this.items[index]),
@@ -1572,6 +1601,7 @@ colors = jQuery.Color.names = {
15721601
this.group.addContainer(this)
15731602
if(!ignoreChildren)
15741603
processChildContainers(this.el, this.options.containerSelector, "enable", true)
1604+
15751605
this.el.on(eventNames.start + "." + pluginName, this.handle, this.dragInitProxy)
15761606
},
15771607
disable: function (ignoreChildren) {
@@ -1595,7 +1625,7 @@ colors = jQuery.Color.names = {
15951625
*/
15961626
$.fn[pluginName] = function(methodOrOptions) {
15971627
var args = Array.prototype.slice.call(arguments, 1)
1598-
1628+
15991629
return this.each(function(){
16001630
var $t = $(this),
16011631
object = $t.data(pluginName)
@@ -1613,6 +1643,19 @@ $(function () {
16131643
$("ol.example").sortable()
16141644
})
16151645
;
1646+
$(function () {
1647+
$("ol.limited_drop_targets").sortable({
1648+
group: 'limited_drop_targets',
1649+
isValidTarget: function (item, container) {
1650+
if(item.is(".highlight"))
1651+
return true
1652+
else {
1653+
return item.parent("ol")[0] == container.el[0]
1654+
}
1655+
}
1656+
})
1657+
})
1658+
;
16161659
$(function () {
16171660
$("ol.nav").sortable({
16181661
group: 'nav',
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
$(function () {
2+
$("ol.limited_drop_targets").sortable({
3+
group: 'limited_drop_targets',
4+
isValidTarget: function (item, container) {
5+
if(item.is(".highlight"))
6+
return true
7+
else {
8+
return item.parent("ol")[0] == container.el[0]
9+
}
10+
}
11+
})
12+
})
13+
;

0 commit comments

Comments
 (0)