Alex
Alex

Reputation: 68406

UI draggable + droppable append anywhere?

I'm using something very similar to this:

http://jqueryui.com/demos/droppable/#shopping-cart

Currently when I drag an item it gets appended to the list.

How can I make it so it gets appended after the item on which I'm hovering on?

Also how can I make each "product category" accept items from other categories? So for example if I drag a "lolcat shirt" on the "bags" category, then the bags category would expand, and allow me to drop the shirt anywhere I want inside it :)

Fiddle Demo

Upvotes: 2

Views: 3848

Answers (2)

Oleg
Oleg

Reputation: 24988

Well, this is awkward. I must have read everything but your requirement of appending the new item after the item hovered over. Changes below + updated jsfiddle.

Answer updated

Multiple sortable/draggable/droppable integration can be a nightmare indeed.

First, we'll make both the cart and the product list into sortables

$("#catalog ul, #cart ol").sortable().disableSelection();

Almost done :) now we need to add custom handling of dragdrop release on the catalogue (move the item to the new subcategory) or on the cart (clone the item to the cart)

Let's start with the cart:

This is the updated part where creating a droppable is moved into a function so it could be reused; it is also no longer created from the cart container but rather from individual items in the cart so they can be individually tracked and have items inserted after them.

//EDIT - for the droppable behaviour to meet the requiremens,
//we need to make individual items in the cart into droppables;
//as more elements are added at runtime, droppable has to be
//re-initiated, otherwise you'll end up only being to drop
//onto the first item in the cart (not cool)
function initDroppable() {
    $("#cart ol li").droppable({
        accept: "#catalog ul li",
        hoverClass: "ui-state-hover",
        drop: function(event, ui) {
            //we're going to clone the item from the cart and
            //insert it after "this", which refers to the item
            //in cart being "dropped onto"
            $("<li></li>").text(ui.draggable.text()).insertAfter(this);
            $("#cart ol li").droppable("destroy");
            initDroppable();
            event.preventDefault();
            return false;
        }
    });
}

//now initialize the cart as a droppable for the first run
initDroppable();

We'll make the catalogue into a droppable and make a nice function as promised above.

var $catalog_items = $("h3" ).droppable({
    accept: "#catalog ul li",
    hoverClass: "ui-state-hover",
    drop: function(event, ui) {
        //reference to the original item that's being dragged
        var $item = $(event.target);
        //well, this is awkward. I couldn't find it in jQuery
        //doco how to find the accordion's list... so we are
        //looking for a "ul" inside of the element that
        //immediately follows the accordion expander element
        //This works out to be "ul inside a div after this h3" :)
        var $list = $("ul", $(this).next());
        //now remove the original item...
        $item.remove();
        //...and add the item to its new parent :)
        //NB simply appending $item didn't work
        $("<li></li>").text(ui.draggable.text()).appendTo($list);
        //new accordion structure = new size
        $catalog.accordion("resize");
        //and trigger the accordion to expand on the correct category
        $(this).click();

        event.preventDefault();
        return false;
    }
});

This pretty much covers it. If you want to see it in action, you can play with my fiddle here: http://jsfiddle.net/ZpaJP/3/

Link updated

Upvotes: 2

jammon
jammon

Reputation: 3464

For the first question: make the items in the target list "droppable" (not the target list itself):

$( "#cart li" ).droppable({
    drop: function( event, ui ) {
        $( this ).siblings( ".placeholder" ).remove();
        $( "<li></li>" ).text( ui.draggable.text() ).insertAfter( this );
    }
});

Same for the second question: make the catalog droppable (similar code).

Upvotes: 3

Related Questions