Nested Sortable Lists

Nov 24, 2009 at 5:00 AM

My goal is this:

1. Create a horizontal plan of parent menus,  The order of the parent menus can be changed by dragging the parents from right to left.
2. Create sub menus for each parent menu.  The sub menu items load in a vertical list beneath each parent. 
    The sub menu items may be sorted vertically,  or may be dragged from one parent to another.

Here is what i have so far:

<!--CTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dt-->


<!--
body {
	font-family: Arial;
	font-size:12pt;
	padding:20px;
	width: 800px;
	margin:auto;
	border:solid 1px black;
	padding-top: 20px;
	margin-top:20px;
}
h1 {
	font-size: 16pt;
}
h2 {
	font-size: 13pt;
}
ul {
	margin:0px;
	padding:0px;
	margin-left:20px;
}
.menuholder {
	background-color:#000;
	width:100%;
	height:35px;
}
#AllMenus {
	width:100%;
	margin:0px;
	padding:0px;
	margin-left:0px;
	list-style-type:none;
	border:none;
	font-size:10px;
}
#AllMenus li {
	float:left;
	min-width:100px;
	border:none;
	padding:0px;
	margin:0px;
}
#AllMenus li div {
	height:33px;
	min-width:114px;
	margin:0px;
	border:solid 1px black;
	text-align:center;
	vertical-align:top;
}
.parentmenu_item {
	width:100px;
	background-color:#000;
	color:#FFF;
	border:1px solid black;
	padding-top:10px;
	padding-bottom:9px;
	padding-right:6px;
	padding-left:6px;
	text-align:center;
	display:block;
	margin-bottom:0px;
	border-right:#242424 1px solid;
	vertical-align:top;
}
.placeHolder div {
	background-color: #0FF !important;
	border: dashed 1px gray !important;
	width:53px;
}
#babylist, #babylist2, #babylist3, #babylist4 {
	width:114px;
	list-style-type: none;
	margin:0px;
	border:none;
	padding:0px;
	padding:none;
}
#babylist li, #babylist2 li, #babylist3 li, #babylist4 li {
	float:left;
	width:100px;
	background-color:#333;
	color:#CCC;
	text-align:left;
	padding:6px;
	border-bottom:1px solid #000;
}
-->


jQuery List DragSort Example

Homepage

PARENT MENUS

<form enctype="application/x-www-form-urlencoded" method="get"> <input id="ParentsortOrder" name="ParentsortOrder" size="100" type="text" /> <button class="submit3">Save & Continue...</button> </form>

<!--For Background Menu Bar --> <!--Menus List -->
    <!--Top Menu -->
  • Menu 1 <!--Child Menus -->
    • My Pictures
    • My Music
    • My Docs
    • My Friends
    • My Books
    • My Computer
    • My Network
    • My Test
    <!--Top Menu -->
  • Menu 2 <!--Child Menus -->
    • Milk
    • Cheese
    • Eggs
    • Bacon
    • Flour
    <!--Top Menu -->
  • Menu 3 <!--Child Menus -->
    • Cow
    • Pig
    • Horse
    • Lamb
    <!--Top Menu -->
  • Menu 4 <!--Child Menus -->
    • Bob
    • Kevin
    • Nancy
    • Stacy
    • Rochelle
<!--End Top Menu Bkr -->
<!--End Background --> <!--MY ATTEMPT TO SORT THE CHILD MENU "BABY LIST" ITEMS INTO A DIFFERENT PARENT OR TO RE ORDER... -->
Nov 24, 2009 at 5:01 AM

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

<script type="text/javascript" src="dragsort-0.3.7.min.js"></script>

<style type="text/css">

body {

font-family: Arial;

font-size:12pt;

padding:20px;

width: 800px;

margin:auto;

border:solid 1px black;

padding-top: 20px;

margin-top:20px;

}

h1 {

font-size: 16pt;

}

h2 {

font-size: 13pt;

}

ul {

margin:0px;

padding:0px;

margin-left:20px;

}

.menuholder {

background-color:#000;

width:100%;

height:35px;

}

#AllMenus {

width:100%;

margin:0px;

padding:0px;

margin-left:0px;

list-style-type:none;

border:none;

font-size:10px;

}

#AllMenus li {

float:left;

min-width:100px;

border:none;

padding:0px;

margin:0px;

}

#AllMenus li div {

height:33px;

min-width:114px;

margin:0px;

border:solid 1px black;

text-align:center;

vertical-align:top;

}

.parentmenu_item {

width:100px;

background-color:#000;

color:#FFF;

border:1px solid black;

padding-top:10px;

padding-bottom:9px;

padding-right:6px;

padding-left:6px;

text-align:center;

display:block;

margin-bottom:0px;

border-right:#242424 1px solid;

vertical-align:top;

}

.placeHolder div {

background-color: #0FF !important;

border: dashed 1px gray !important;

width:53px;

}

#babylist, #babylist2, #babylist3, #babylist4 {

width:114px;

list-style-type: none;

margin:0px;

border:none;

padding:0px;

padding:none;

}

#babylist li, #babylist2 li, #babylist3 li, #babylist4 li {

float:left;

width:100px;

background-color:#333;

color:#CCC;

text-align:left;

padding:6px;

border-bottom:1px solid #000;

}

</style>

</head>

<body>

<h1>jQuery List DragSort Example</h1>

<a href="http://dragsort.codeplex.com/">Homepage</a><br/>

<br/>

<h2>PARENT MENUS</h2>

<form name="sortForm" method="get">

<input name="ParentsortOrder" type="text" id="ParentsortOrder" size="100">

<button type="submit" class="submit3" name="submit"><span>Save & Continue...</span></button>

</form>

<div style="clear:both;"></div>

<br />

<br />

<div style="background-image:url(../Users/all/bkri/fs/phase_8.jpg); min-width:500px; height:500px; max-width:1920px;">

<div class="menuholder">

<!--For Background Menu Bar -->

<!--Menus List -->

<ul id="AllMenus">

<!--Top Menu -->

<li id="P1">

<div> <span class="parentmenu_item"> Menu 1 </span>

<!--Child Menus -->

<ul id="babylist">

<li id="s1"><span id="spandex">My Pictures </span></li>

<li id="s2"><span id="spandex">My Music </span></li>

<li id="s3"><span>My Docs </span></li>

<li id="s4"><span>My Friends </span></li>

<li id="s5"><span>My Books </span></li>

<li id="s6"><span>My Computer </span></li>

<li id="s7"><span>My Network </span></li>

<li id="s8"><span>My Test </span></li>

</ul>

</div>

</li>

<!--Top Menu -->

<li id="P2">

<div> <span class="parentmenu_item"> Menu 2 </span>

<!--Child Menus -->

<ul id="babylist2">

<li id="s9"><span>Milk</span></li>

<li id="s10"><span>Cheese </span></li>

<li id="s11"><span>Eggs </span></li>

<li id="s12"><span>Bacon </span></li>

<li id="s13"><span>Flour </span></li>

</ul>

</div>

</li>

<!--Top Menu -->

<li id="P3">

<div> <span class="parentmenu_item"> Menu 3 </span>

<!--Child Menus -->

<ul id="babylist3">

<li id="s14"><span>Cow</span></li>

<li id="s15"><span>Pig </span></li>

<li id="s16"><span>Horse </span></li>

<li id="s17"><span>Lamb </span></li>

</ul>

</div>

</li>

<!--Top Menu -->

<li id="P4">

<div> <span class="parentmenu_item"> Menu 4 </span>

<!--Child Menus -->

<ul id="babylist4">

<li id="s19"><span>Bob</span></li>

<li id="s20"><span>Kevin </span></li>

<li id="s21"><span>Nancy </span></li>

<li id="s22"><span>Stacy </span></li>

<li id="s23"><span>Rochelle </span></li>

</ul>

</div>

</li>

</ul>

</div> <!--End Top Menu Bkr -->

</div> <!--End Background -->

<script type="text/javascript">

// this tells the sort script to do its thing

$("#AllMenus").dragsort({ dragSelector: "span", dragEnd: saveOrder });

 

// this is the function that puts the new sort order into a string

function saveOrder() {

var serialStr = "";

$("#AllMenus li").each(function(i, elm) { serialStr += (i > 0 ? "," : "") + $(elm).attr("id"); });

 

// this dynamically updates string to hidden form field

document.getElementById('ParentsortOrder').value = serialStr;

};

</script>

<!--MY ATTEMPT TO SORT THE CHILD MENU "BABY LIST" ITEMS INTO A DIFFERENT PARENT OR TO RE ORDER... -->

<script type="text/javascript">

$("#babylist, #babylist2, #babylist3, #babylist4").dragsort({ dragSelector: " li > #spandex", dragBetween: true });

</script>

<div style="clear:both;"></div>

</body>

</html>

Coordinator
Nov 25, 2009 at 9:28 AM
Edited Nov 25, 2009 at 9:45 AM

Interesting example, thanks for posting this. I guess the first problem is that I haven't really provided very good documentation, so will look at doing that at some stage, but here is a quick explanation. jQuery uses CSS selectors to retrieve page elements so:

$("#AllMenus").dragsort({ dragSelector: "span", dragEnd: saveOrder });
         ↑                                                   ↑
  matches the UL tag                        matches any span elements inside the UL tag (i.e. #AllMenus span)

The dragSelector is used to specify what element you need to click on if you want to drag and drop the LI tag (if it's not specified then the LI tag is used so that clicking anywhere inside it will move it). Therefore the problem is that when you click on the span tag in the child menu you will end up moving the parent menu as well, so the fix is simple enough:

$("#AllMenus").dragsort({ dragSelector: ".parentmenu_item", dragEnd: saveOrder });

The second problem has highlighted a bug in the code. When you click on the element specified by the drag selector I first test to see if it's the LI tag and if not I then keep looking at the parent elements until I find the LI tag and then proceed to move that tag to where you cursor is. The problem is I'm not stopping at the first parent LI tag I find and so I move all parent LI tags i.e. the parent menu as well. In your case however there's no need to make a child element the drag selector so leaving it at the default of LI won't experience this bug (will be fixed in the next version released):

$("#babylist, #babylist2, #babylist3, #babylist4").dragsort({ dragBetween: true, dragEnd: saveOrder });