Search code examples
jqueryjquery-uiinputdroppable

jQuery UI Droppable - Show default elements based on saved list (& add extra drop zones)


Full JSFiddle of my current setup: https://jsfiddle.net/w27g3xp2/1/

You'll see that there's an input box with some pre-defined values. The goal is to create and position the 4 droppable elements, based on the inputs in the field, so that they are shown in the drop boxes. Currently, when I drop in an element from the list, the input field is completely cleared.

An additional challenge is the "+", that successfully adds additional drop zones, but these zones are not registered as "droppable" zones, so they're currently useless. Any pointers, tips or documentation would be really appreciated.

Code:

$(".social-msl-link-label").draggable({
    connectToSortable: ".social-msl-group-list",
    revert: "invalid",
    helper: "clone"
});

var orderMSLids = [];
$(".social-msl-links-order li.social-msl-drop").droppable({
    accept: ".social-msl-link-label",
    tolerance: 'pointer',
    greedy: true,
    hoverClass: 'highlight',
    drop: function(ev, ui) {
        orderMSLids = [];
        $(ui.draggable).clone(true).detach().css({
            position: 'relative',
            top: 'auto',
            left: 'auto'
        }).appendTo(this);

        orderMSLids.push($(this).find('.social-msl-link-label').attr('id'));

        $(this).siblings().filter(function() {
            return $(this).html().trim() === $(ui.draggable).html().trim();
        }).empty();

        // edited
        str = [];
        $(".social-msl-links-order li").each(function( index ) {
            //console.log( index + ": " + $( this ).children().attr('id') );
            var res = $( this ).children().attr('id');
            if (res) {
                str.push(res);
            }
        });

        var string = str.join(",");
        console.log(string);
        $('#msl-order').val(string);

    }
});

$('.social-msl-add').click(function() {
    $('<li class="social-msl-drop"></li>').insertBefore('.social-msl-add');
});

Solution

  • For your first issue, you can simply retrieve the value property of the #msl-order element, split the value based on the , delimiter, iterate over the returned values, and then clone the corresponding element and append it to the first empty droppable container:

    Updated Example

    $('#msl-order').prop('value').split(',').forEach(function(id) {
      var $droppable = $('.social-msl-drop.ui-droppable:empty').first();
      if (id) {
        $('.draggable #' + id).clone(true).appendTo($droppable);
      }
    });
    

    For your second issue, you need to re-initialize the droppable settings. In the example below, I save the initial droppable settings object in a variable named droppableOptions, then I initialize these options before inserting the new element:

    Updated Example

    $('.social-msl-add').click(function() {
      var $droppable = $('<li class="social-msl-drop"></li>').droppable(droppableOptions);
      $droppable.insertBefore('.social-msl-add');
    });