Mariusz Grodek
Mariusz Grodek

Reputation: 639

Jquery UI Sortable with fixed places

I have some snippet of code which presents two sortable lists connected to each other. Everything is just working great.

Demo - jsFiddle example

In demo the letters are dropped at the beginning of the sortable or at the end or between. In general all letters are squizzed, no whitespaces. It is natural behaviour of sortable. But now i would like to move (drag&drop) letters differently.

I would like to move letter from position 3 [Letter N for example] to be dropped at position 3 on the list below not on the left side. And except that i would like that the sortable list [which is now without letter N] not to be squizzed but the gap between them should remain. Except that I would like to keep sortable behaviour on ul elements so that i will be able to sort letters/whitespaces with each other, move the gap to other place but only on the same sortable list.

I tried to do it with span in li element and then just disconnect the lists and use just draggable and droppable but I have no idea how to make it right. I tried two ways.

FIRST : Add span to li elements so that li elements will become some kind of a bucket (only one letter can be in each bucket). And then just add:

    $("#letters li span").draggable({
         connectToSortable: "#subword",
         revert: "invalid"
    });

    $("#subword li span").draggable({
         connectToSortable: "#letters",
         revert: "invalid"
    });

but it only puts span at the end of the sortable and not inside the li element which i drag&drop to.

SECOND : Add on li droppable and on span draggable, but the i cannot use sortable on li. I always will drag span element which is on top of li.

Could someone help me with it because I am in dead end. If something is not well explained please ask. Thanks in advance!

Upvotes: 1

Views: 2639

Answers (1)

Proqb
Proqb

Reputation: 335

Demo: http://jsfiddle.net/proqb/5qupZ/

Here is a short snippet of JS:

$(function () {
    $("#sortable1").sortable();
    $("#sortable2").sortable();

    $(".droppable").droppable({
        accept: ".alienNode",
        drop: function (event, ui) {

                    ui.draggable.parent().droppable("enable");

            $(this).append("<div class='alienNode'>" + ui.draggable.html() + '</div>');

            ui.draggable.remove();

            $(this).find(".alienNode").draggable({
                handle: ".handler",
                revert: "invalid"
            });

            $(this).droppable("disable");

        }
    });

    $(".prerender").droppable("disable");

    $(".alienNode").draggable({
        handle: ".handler",
        revert: "invalid"
    });
});

The general idea of this solution is that you do not use the connectedSortable.

There are 2 sortable lists instead. Each List contains Draggable Droppables (which are transparent right now - if you want to see them - you can give them background color attribute). Those Children Nodes accept only element with a certain Class Atribute so you can drop only a specific node in there. And Finally there is an inner node, which is a pure Draggable that has this Fixed Class Attribute and can be dropped in both lists.

The length of the sortable lists can be of course dynamically changed, so you do not have to limit yourself with a fixed number of starting elements, however that is up to you and your needs.

If you would like to use my solution there are a few cases that you would have to solve such as:

1) customization of onRevert event (which is not a defined event in JQuery and its misfunction can lead to duplication of nodes), or you can substitute its mechanism with something else.

2) making a background image grid for the sortable UL-s, so you will be able to view where the element can be dragged at, or perhaps implementing a placeholder mechanism.

3) making apropriate handlers so the nodes can be dragged intuitively. Currenty you can drag either by letter (which is a handler for the inner node), or by the black background - which acts like a handler for the inner node container.

4) making draggables stick to the drop areas might also be a good idea.

I don't think the mechanism you have developed before could work in my solution but you can try to reimplement it in my example.

Finally - If you meet any other problems You can always switch to YUI which has a lot more options if you want to customize the mechanisms faster and more accurately, here is the Drag&Drop Section: http://yuilibrary.com/yui/docs/dd/ :)

I hope some of this will help you anyway :)

Upvotes: 1

Related Questions