Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to drag one or more items to an element using both Draggable and Selectable JQuery

I'd like to know how to drag one or more items (individual Person records in my case, via their avatar photo) to a target (in my case a list of cities) and then update the database for the dragged items with details of the item they were dragged to.

I have this working for single items at the moment.

I have a sidebar with a list of locations which I retrieve from a database with EntityFramework:

<ul>
<li class="droppable">
    <span>Sydney</span>
</li>
<li class="droppable">
    <span>Brisbane</span>
</li>
<li class="droppable">
    <span>Melbourne</span>
</li>
</ul>

In my main window I have a grid of people's images and I'm using Jquery UI selectable to enable these to be selected:

<ul class="people-list" id="selectable">
    @foreach (var item in Model.People)
    {
        <li>
            <img src="@item.Photo" style="width:100%" class="img-polaroid" />                
        </li>
    }
</ul>

 $(function () {
    $("#selectable").selectable({
        selected: function (event, ui) {
            if ($(ui.selected).hasClass('click-selected')) {
                $(ui.selected).removeClass('ui-selected click-selected');

            } else {
                $(ui.selected).addClass('click-selected');

            }
        },
        unselected: function (event, ui) {
            $(ui.unselected).removeClass('click-selected');
        }
    });

});

What I'd like to do, is that once the user has selected one or more people, for them to be able to drag the selected people to one of the Locations, and then update the database.

So if the user drags PersonID 4,5 and 9, to 'Sydney' then I need to update the database asyncronously to perform this.

I've added JQuery Draggable and Droppable and I can drag individual people to one of the Locations, and then update the database, but I can't get it to work with selectable to allow multiple items to be selected.

$(function () {
    $(".img-polaroid").draggable({
        containment: "document",
        helper: 'clone',
        opacity: 0.70,
        zIndex: 10000,

    });
    $(".droppable").droppable({
        hoverClass: "ui-state-hover",
        tolerance: "pointer",
        drop: function (event, ui) {
            $.ajax({
                type: "POST",
                url: '/Person/UpdateLocations/' + $(this).attr("id") + '|' + $(ui.draggable).attr("id"),
                success: function (data) {
                    $('.draggable').draggable('destroy');
                    $('#successMsg').empty();
                    $('#successMsg').append(data);
                    $('#successDiv').show();
                    $('.draggable').draggable({ revert: true });
                }
            });
        }
    });
});
like image 626
Evonet Avatar asked Jun 01 '14 07:06

Evonet


1 Answers

I find out that .selectable() and .draggable() are not working on a same element. My suggestion is to create your own multi-select behaviour.

Embedding value (id) to HTML elements

Embed ids, as value, to HTML elements accordingly both for the cities and persons, eq : <li class="droppable" data-val="sydney"><span>Sydney</span> </li> and <img src="" class="img-polaroid" data-val="4"/>.

Imitating Multi-select

Every selected element will be tagged by specific class, defined in selectedClass = "ui-selected". This class will be toggled by click event. An element may not selected on the drag event, therefore we need to add selectedClass on draggable.start.

Drag

.draggable only works on single dragged element (CMIIW), thus we move the selected element by changing the top and left properties of the elements. Set position=relative of the #selectable element.

Drop

Actions need to be done on droppable.drop callback : Prepare data and perform AJAX request. If the AJAX request succeed the selectable elements will be removed and update message. If AJAX request failed the selectable elements are going to placed back on their original position.

Please take a look on the example : http://jsfiddle.net/marson/zSCAb/131/. Hope this helps.

like image 130
marson parulian Avatar answered Oct 15 '22 09:10

marson parulian