Which event(s) to use with Sortables and connectWith?

I'm trying to create a menu-builder using two unordered lists. I am using jQuery sortables to create the interface.

I have one on the left which contains the site's drop-down menu hierarchy. The list on the right is unused pages not appearing in the navigation. Here are the events I need to track:
1. When an item is dragged from the list on the right and dropped into the list on the left.
2. When an item is dragged from the list on the left and dropped into the list on the right.
3. When an item is dragged up or down in the list on the left.

The problem is the events lists these triggers:
start, sort, change, beforeStop, stop, update, receive, remove, over, out, activate, deactivate

I have tried a ton of combinations and troubleshooted for hours trying figure out the way to handle my events to support the way I'm keeping up with this stuff. Some of these events work for some actions, but not for others, so I must setup multiple events, and by the time I'm done, I end up with several events, occurring in the wrong order.

At this point, I have it just about figure out, however when an item is dragged from the list on the left to the list on the right (removed from menu), the remove event occurs before the stop event and the stop event overwrites what I did on the remove event.

I guess what I'm saying is I'm sure there is a smarter way to do this, so let me explain what i'm doing:
My menu items are stored with its Parent Element ID (menu_parent). If menu_parent IS NULL then it's not in the navigation. If it's 0, then it's part of the root navigation. Any other integer value is the Parent Item's ID.

So, that being said, when an item is dragged from left to right, I need the "remove" event to occur and simply update the element in the DB with a NULL value for menu_parent. All other events need to record the position as well as the parent. Can you please help? I have attached my JS code.

On a side note, does anyone know how to make the left list accept an infinite # of nested lists?  I tried this:
http://code.google.com/p/nestedsortables/wiki/NestedSortableDocumentation However it uses Interface and not jQuery UI. Any other working plugins out there?
// this in the document ready function
$("#sortable-list ul").sortable({
	connectWith: ["#selection-list ul"],
	receive: function(e,ui){
		sortAction(e,ui,'receive');
	},
	stop: function(e,ui){
		sortAction(e,ui,'stop');
	},
	remove: function(e,ui){
		sortAction(e,ui,'remove');
	}
});
	
$("#selection-list ul").sortable({
	connectWith: ["#sortable-list ul"]
});
 
// this is my main execution function
function sortAction(e,ui,a){
	var proceed = true;
	var el_id = $(ui.item).attr('id');
	id = el_id.replace("ele-","");
	var params = "action=update_menu_item&jsa="+a+"&item_id="+id;
	if($("#"+el_id).parents("li").length > 0){
		var parent_id = $("#"+el_id).parents("li").attr('id');
		parent_id = parent_id.replace("ele-","");
		var parent_el = $("#ele-"+parent_id+" ul");
	} else {
		parent_id = "0";
		var parent_el = $("#sortable-list ul");
	}
	if(a == "remove"){
		parent_id = "NULL";
	} else {
		var new_order = "";
		var kids = parent_el.children("li");
		$.each(kids, function(e){
				var tmp = $(this).attr("id");
				tmp = tmp.replace("ele-","");
				new_order = (new_order == "") ? tmp : new_order + ","+tmp;
			});
		if(a == "stop" && new_order == ""){
			proceed = false;
		} else {
			params += "&new_order="+new_order;
		}
	}
	params += "&parent_id="+parent_id;
	if(proceed){
		$.ajax({
			type: "POST",
			url: "/stoneCMS/stone/stone_ajax.php",
			data: params,
			success: function(result){
				if(result != ""){
					if(result.indexOf("<script>") == -1){
						// do something...
					} else {
						eval($(result).html());
					}
				} else {
					$("#menu_result").show();
					var newHTML = (a == "remove") ? 'Item removed from menu.' : ((a == "receive") ? 'Item added to menu' : 'Menu updated and sort positions saved.');
					if($("#menu_result").html() == newHTML){
						$("#menu_result").css("background-color","#BCD985");
						setTimeout(function(){
							$("#menu_result").animate({
									backgroundColor: "#FFC"
								}, 1000);
							}, 500
						);
					} else {
						$("#menu_result").html(newHTML);
					}
				}
			} // end success function
		}); // end AJAX
	}
}
 
 
// sample HTML
<h1>Menu Manager</h1>
<div id="sortable-list">
	<h3 class="caption">Website Menu</h3>
	<ul class="first">
		<li class="sortable-element" id="ele-1">Home</li>
		<li class="sortable-element" id="ele-7">Information<ul>
			<li class="sortable-element" id="ele-6">About Us</li>
			<li class="sortable-element" id="ele-8">Business Services</li>
			<li class="sortable-element" id="ele-19">Communications</li>
			<li class="sortable-element" id="ele-40">Records</li>
			<li class="sortable-element" id="ele-23">Youth Services</li>
		</ul></li>
		<li class="sortable-element" id="ele-37">Events</li>
		<li class="sortable-element" id="ele-38">Statistics</li>
		<li class="sortable-element" id="ele-13">Employees</li>
		<li class="sortable-element" id="ele-14">Resources<ul>
			<li class="sortable-element" id="ele-47">Files</li>
			<li class="sortable-element" id="ele-15">Links</li>
		</ul></li>
		<li class="sortable-element" id="ele-35">Directory<ul>
			<li class="sortable-element" id="ele-48">Staff</li>
			<li class="sortable-element" id="ele-49">Information Technology</li>
			<li class="sortable-element" id="ele-52">Records</li>
			<li class="sortable-element" id="ele-53">Training</li>
		</ul></li>
		<li class="sortable-element" id="ele-17">Contact</li>
	</ul>
</div>
	
<div id="selection-list">
	<h3 class="caption">Other Pages</h3>
	<ul class="first">
		<li class="draggable-element" id="ele-12">Radio</li>
		<li class="draggable-element" id="ele-32">News</li>
		<li class="draggable-element" id="ele-33">Site Map</li>
	</ul>
</div>

Open in new window

LVL 7
bdichiaraAsked:
Who is Participating?
 
bdichiaraConnect With a Mentor Author Commented:
I ended up doing something like this, basically setting up different actions for each event, rather than one global action for the whole thing.
$("#sortable-list ul").sortable({
		connectWith: ["#selection-list ul"],
		receive: function(e,ui){
			addAction(e,ui);
			sortAction(e,ui);
		},
		remove: function(e,ui){
			removeAction(e,ui);
		},
		stop: function(e,ui){
			sortAction(e,ui);
		},
		out: function(e,ui){
			// secret to nested lists
		}
	});

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.