I'm using jQuery 1.7 and jQuery UI 1.8 from Google's CDN (so I have the latest versions).
I have two elements on my page, a header nav, and a content area with containers that correspond to each header list item. Currently, I have Sortable attached to both, allowing me to rearrange the visual order of both the navigation elements, and the content containers (separately). The behaviour I am trying to achieve is such that when I drag a navigation element, the content container moves with it, and when I drop the navigation element in a new position within the list, the content container sticks to its new position in the content area as well. The website I am working on is an intranet page, so I cannot provide a link, but I have included a diagram below:
Navigation:
NavOne...NavTwo...NavThree
Content:
ContentOne...ContentTwo...ContentThree
After dragging NavThree between NavOne and NavTwo, the whole arrangement should look like this:
Navigation:
NavOne...NavThree...NavTwo
Content:
ContentOne...ContentThree...ContentTwo
Is there a simple way to link the two Sortables so they behave in this fashion? It doesn't really have to be smooth or "live" (though I would really like it if it could be). I'm OK with it not refreshing the second sortable list until the reordering in the first list is completed (dropped).
I have already asked this question over at the jQuery UI forums and waited a week for a response: [LINK]
Here's a sample of the skeleton I'm testing this on before moving it to the actual project:
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<html>
<head>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<style>
/* This is my CSS */
/* Basic reset -- outline for debugging */
* {padding: 0px; margin: 0px; outline: 1px solid rgba(0,0,0,0.1);}
html {width: 100%; height: 100%;}
body {width: 100%; height: 100%;}
/* Main styles */
.containerDiv {
overflow-x: scroll;
overflow-y: hidden;
width: 800px;
height: 600px;
white-space: nowrap;
float: left;
}
.itemDiv {
width: 200px;
height: 500px;
display: inline-block;
}
.navBar ul, .navBar li {
display: inline;
}
</style>
</head>
<body>
<!-- This is my HTML -->
<div class="navBar">
<ul>
<li id="nav1">Navigation 1</li>
<li id="nav2">Navigation 2</li>
<li id="nav3">Navigation 3</li>
</ul>
</div>
<div class="containerDiv">
<div class="itemDiv" id="item1">Item 1</div>
<div class="itemDiv" id="item2">Item 2</div>
<div class="itemDiv" id="item3">Item 3</div>
</div>
</body>
<script>
/* This is my JavaScript */
// Make containerDiv children sortable on X-axis
$(".containerDiv").sortable({
axis: "x"
});
// Make nav children sortable on x-axis
$(".navBar").sortable({
axis: "x",
items: "li"
});
// Bind sorting of each (.navBar li) to its corresponding (.containerDiv .itemDiv):
$(".navBar li").bind("mouseup", function(event,ui){
// If I use "sortupdate" I get little to no response. If I use "mouseup",
// I can at least get an alert to return the value of thisId.
// Note: I am sad that console.log is blocked in Firefox,
// because its DOM inspector is better than Chrome's
// the (.navBar li) have ids of "nav1, nav2" and so on,
// and the (.containerDiv .itemDiv) have corresponding ids of "item1, item2"
// which is my way of attempting to make it easier to link them.
// This line is my attempt to target the (.containerDiv .itemDiv) which directly
// corresponds to the (.navBar li) which is currently being sorted:
var tempId = "#" + $(this).attr('id').replace("nav","item");
// When this (.navBar li) is updated after a sort drag,
// trigger the "sortupdate" event on the corresponding (.containerDiv .itemDiv):
$(tempId).trigger("sortupdate");
});
</script>
</html>
In that week I've tried many different possible solutions and none of them have quite worked how I want them to. I feel like this should be relatively simple, but in a week of working on it (off and on), I haven't gotten anywhere useful with it.
I've already read the following related threads while looking for some insight:
- dragging multiple list items simultaneously
- JQuery Draggable + Sortable: How to tell if item was actually added to my sortable list?
- Sorting multiple items at the same time using jQuery UI
- jQuery UI Sortable: Multi-item select
- Is it possible to link two jquery.ui draggables together?
I think that, failing all else, it should be possible for me to at least serialize the sortable, ajax it to the server, then have the second list update based on the serialized data, but I would like to keep this on the local browser to reduce calls to the server (until the user chooses to save the new arrangement to their account).
So, StackOverflow...is this a reasonable/achievable task that I'm trying to accomplish, or am I just bashing my head against the bricks here? Should I look for a different way to do it? I would like to avoid modifying the Sortable plugin if possible, but if I must, then I shall.
I've never used jsFiddle before, but I realized it would probably help, so here it is: http://jsfiddle.net/34u7n/1/