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

Posted on 2008-11-11
Last Modified: 2012-05-05
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: 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){



	stop: function(e,ui){



	remove: function(e,ui){





$("#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;



			type: "POST",

			url: "/stoneCMS/stone/stone_ajax.php",

			data: params,

			success: function(result){

				if(result != ""){

					if(result.indexOf("<script>") == -1){

						// do something...

					} else {



				} else {


					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){




									backgroundColor: "#FFC"

								}, 1000);

							}, 500


					} else {




			} // 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>


		<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>


		<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>


		<li class="sortable-element" id="ele-17">Contact</li>




<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>



Open in new window

Question by:bdichiara
    1 Comment
    LVL 7

    Accepted Solution

    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){
    		remove: function(e,ui){
    		stop: function(e,ui){
    		out: function(e,ui){
    			// secret to nested lists

    Open in new window


    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Join & Write a Comment

    Introduction A frequently asked question goes something like this:  "I am running a long process in the background and I want to alert my client when the process finishes.  How can I send a message to the browser?"  Unfortunately, the short answer …
    Introduction If you're like most people, you have occasionally made a typographical error when you're entering information into an online form.  And to your consternation, the browser remembers the error, and offers to autocomplete your future entr…
    The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
    The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

    734 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now