Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery Draggable Droppable and Sortable at the same time for DOM Manipulation

I am trying to setup somme kind of drag and drop wysiwyg editor using JQuery UI.

I have succesfully setup the elements but they have a strange behavior.

It is almost impossible to sort items because of the constant flickering.

i setup my draggables like this:

el.draggable({
    containement:'.main-form-container',
    revert: "invalid",
    connectToSortable: '.sortable'
}).disableSelection();

If i dont set it as draggable the sortable will place the placeholder on itself! why?

Sometimes when an element is dropped into another it becomes ONE draggable element and seem tobe glued together. though that seems fixed with overriding sortable update:

update: function (event, ui) {
        $(ui.item).css({
            position: 'relative',
            top:0,
            left:0,
            width: 'auto'
        });

        // init droppable draggable and sortable on this item
        setupDandD($(ui.item));
    }

and the setupDandD method:

setupDandD($('.form-container'));

    function setupDandD(el) {
        el.draggable({
            containement:'.main-form-container',
            revert: "invalid",
            connectToSortable: '.sortable'
        }).disableSelection();

        el.droppable({
            accept: '[data-section="toolbox"]',
            greedy: true,
            hoverClass: 'droppable-hovered',
            drop: handleDrop
        }).disableSelection();

        el.filter('.sortable').sortable({
            tolerance:'pointer',
            containement:'.main-form-container',
            connectWith: ".sortable:not(#" + $(this).id + ")",
            revert: 'invalid',
            helper: function () {
                return $(this);
            },
            update: function (event, ui) {
                console.log('here');
                $(ui.item).css({
                    position: 'relative',
                    top:0,
                    left:0,
                    width: 'auto'
                });
                setupDandD($(ui.item));
            }
        }).disableSelection();
    };

I guess I need to pickup some event somewhere on the sortable but i am quite lost now...

like image 698
Jmorvan Avatar asked Nov 21 '13 14:11

Jmorvan


People also ask

How to use jQuery draggable ()?

This is done by clicking on the object to be dragged using mouse and dragging it anywhere within the view port. This feature of jQueryUI is helpful in adding interaction animations to the web pages to make them more powerful and interactive. This is a guide to jQuery draggable ().

What is droppable method in jQuery UI?

Droppable () Method: This method allows the elements to be dropped with the help of mouse. Using jQuery UI, we can make the DOM (D ocument O bject M odel) elements to drop anywhere within the view port on the specified target. This can be done by clicking on the draggable object by mouse and drop it on the specified target.

How to make the DOM elements drop anywhere in jQuery UI?

Using jQuery UI, we can make the DOM ( D ocument O bject M odel) elements to drop anywhere within the view port on the specified target. This can be done by clicking on the draggable object by mouse and drop it on the specified target. The droppable () method has two forms and the use of each form depends on the requirement. These are as follows :-

How to make the DOM elements drag anywhere within the viewport?

This method allows the elements to be dragged with the help of mouse. Using jQuery UI, we can make the DOM ( D ocument O bject M odel) elements to drag anywhere within the view port. This can be done by clicking on the draggable object by mouse and dragging it anywhere within the view port.


1 Answers

Well well! I found it!

Actually my biggest mistake was to mix droppable and sortable at the same time. I just had to use sortables and draggables with the connectToSortable option set.

The other weird behavior I had was the sortable trying to insert into itself. This is because sortable "connectWith" was set to a selector that returned self and therefor it instantly placed the placeholder on self when dragged. Quite logical actually!

To overcome this I just surrounded each child sortable with a div. It makes the div a sortable item and prevents triggering the events on self.

One thing to take into consideration when using draggable+sortable is that the sortable will always clone the object as it was when drag started. Meaning that even if you use a custom helper on the draggable, it will still insert the original item. For this I had to replace the item in the "stop" event of the sortable by the one i wanted if it came from my toolbox:

$('.main-form-container').sortable({
    placeholder: "sortable-placeholder",
    opacity: .35,
    connectWith: ".sortable",
    stop: function (e, t) {

        if (t.item.attr('data-section') == "toolbox") {
            $(t.item).replaceWith(createContainer());
        }

        $(".sortable").sortable({
            opacity: .35,
            placeholder: "sortable-placeholder",
            connectWith: ".sortable"
        }).disableSelection();
    }
}).disableSelection();

and here is the working fiddle: http://jsfiddle.net/jmorvan/ag659/

I realize there is probably a cleaner way of doing this last fix by overriding some maybe undocumented event in sortable/draggable, but that did the trick for me!

like image 124
Jmorvan Avatar answered Nov 15 '22 00:11

Jmorvan