Moved to: WoodyHayday.com
Woody Hayday

Fresh Ideas

Hi there! This is my old blog, I don't hang around here much.
You can now find me trying to mix things up here:
Visit WoodyHayday.com Subscribe To My Email List

Unable to drop JQuery sortable onto empty list? Hack solution

The problem: You have a multi column (or area) JQuery UI Sortable (these are neat) which only needs to show a “drop zone” when the user has started to drag a sortable object.

The JQuery documentation for this doesn’t account for the reality of the above, its all very well if you want the empty column/div to SHOW all the time as empty, that is remain as some sort of visible placeholder, but if the empty list should show as empty, until an object is ready to be dropped on it then JQuery sortable’s don’t work. It all comes down to dimensions, if an empty list exists without a height value, you can’t drop onto it.

More specifically, if an empty jquery-sortable list exists without a specific height set at the point of [.sortable start] (that is BEFORE the event is fired) then you just cannot drop the sortable.

the JavaScript Code
Image by Dmitry Baranovskiy

I played with fixing this by adjusting each empty list (in the example belows case #col1,#col2,#col3) to have a defined height (and background, which looks nice) within the sortable “start” option, but this just creates boxes (or landing pads/zones) you can see, but not drop on.

Long and short of it – the solution to being able to drop jquery sortable’s onto invisible empty lists is to bind a function which adds a css class (or sets the height specifically) to the empty (invisible) sortable list when a user clicks one of the goal objects. This is then fired BEFORE the sortable takes hold and so creates drag-droppable landing zones for the users held sortable. It then uses the sortables “stop” property to remove the class it has added to any columns which have it.

function sortAndDrag() {
    
	//show BEFORE sortable starts
     $("#col1, #col2, #col3").bind('click mousedown', function(){
          $(".col").each(function (c) {
                if ($("div", this).size() == 0) {
                    $(this).addClass("colZoneEmpty")
                }
            })
     });
    
	//enable sortable
    $("#col1, #col2, #col3").sortable({
        revert: true,
        connectWith: ".col",
        stop: function (a, d) {
            $(".col").removeClass("colZoneEmpty");
	    //any ajax processing
        }
    });
	
}
//in this example 3 column div's exist with the id's 'col1','col2','col3', all of which have the class 'col' 
//colZoneEmpty is a css class which makes the empty list visible

There are of course improvements you could make here, like checking the users dragging before setting any styling, but this quick hackaround works where it shouldn’t.

This entry was posted in Javascript, Snippets, Web Development and tagged , . Bookmark the permalink. Both comments and trackbacks are currently closed.

3 Comments

  1. Chris Nanda
    Posted November 1, 2011 at 5:20 pm

    Awesome fix and timing! This has been an issue I have been running into for the past day, and couldn’t find out why my dynamicly resized divs wouldn’t accept the dragged object. Maybe submit a suggestion to add an init event to the sortable, to run before any other functionality is ran?

  2. Posted November 2, 2011 at 9:15 am

    All good Chris, I actually ended up adding another layer to this which worked a bit better, and then changed it again. In the end, if you can add handles they are a better solution, the way I utilised them I made jQuery add a handle img to the draggable div on mouseover, so they weren’t too invasive, from there the whole thing works a little better. Definitely a good idea to suggest a pre-init though, will do!

  3. Posted April 13, 2012 at 9:17 pm

    Nice post. My situation is a table-based sortable list and it works a bit differently. Good to know people are talking about this online though. Thanks for posting.

Woody Hayday

Comments Archive

Hi there. This is my old blog and it's archived, so you can no longer post new comments on this post (Unable to drop JQuery sortable onto empty list? Hack solution).

Read my new blog about writing software and stories at WoodyHayday.com

The New Blog
WoodyHayday.com
A Quote..
"The purpose of life seems to be to acquaint a man with himself"
Emerson
Old Random Projects
    © Woody Hayday 2008-2017