Lonergan6275
Lonergan6275

Reputation: 2028

jQueryUI Sortable duplicating elements after reinitialising draggable

I am using a combination of JqueryUI Draggable and Sortable to select images from a grid and drag them into a sort-able container where they can be re ordered. the problem is when i load more images i need to reinitialise draggable to include the added items.

https://jsfiddle.net/Lpj8jthk/2/

Initialise Drag

function initDragAndDrop(){
    $( ".ui-draggable" ).draggable({
        opacity: 1.0,
        helper: 'clone',
        revert: 'invalid',
        connectToSortable: '#drop-area'
    });
    $("#drop-area").sortable({
        axis:"x",
        connectWith: '.connectedSortable'
    });

}

$( document ).ready(function() {
    load_draggable_images(track_page); //load content
    initDragAndDrop();
});

load more button handeler

$("#load-more-draggable-images").click(function (e) { //user clicks on button
    track_page++; //page number increment everytime user clicks load button
    load_draggable_images(track_page); //load content

    initDragAndDrop();
});

function load_draggable_images(track_page){
    // $('.animation_image').show(); //show loading image

    $.post( 'includes/load-images.php', {'page': track_page}, function(data){

        if(data.trim().length == 0){
            //display text and disable load button if nothing to load
            $("#load_more_button").text("No more records!").prop("disabled", true);
        }

        var parsed = JSON.parse(data);
        // $("#images-container").empty();
        $.each(parsed, function(k,v){
            var name =  v['filename'].split(".").shift()
            var htmlString = "<div class='tile' data-timestamp='" + v['time']+ "'>" +
            "<div>"+
            "<img class='ui-draggable' src='" + v['thumbnail'] + "'> "+
            "<p>" + name + "</p>"+
            "</div> <br> "+
            "</div> ";
            $("#images-container").append(htmlString);
        });

        initDragAndDrop();
        //scroll page to button element
        // $("html, body").animate({scrollTop: $("#load_more_button").offset().top}, 800);

        //hide loading image
        // $('.animation_image').hide(); //hide loading image once data is received
    });
}

https://jsfiddle.net/Lpj8jthk/2/

Upvotes: 0

Views: 622

Answers (1)

Twisty
Twisty

Reputation: 30883

In your success callback, I would perform:

$("#images-container").sortable("refresh");

Read More: http://api.jqueryui.com/sortable/#method-refresh

Update

From the fiddle, there are a few things I would suggest.

JavaScript

var track_page = 1;

function initDrag($t) {
  $t.draggable({
    opacity: 1.0,
    helper: 'clone',
    revert: 'invalid',
    connectToSortable: '#drop-area'
  });
}

function load_draggable_images(track_page) {
  $("#adverts-container").append(makeImage("https://placehold.it/100x100", "ui-draggable"), makeImage("https://placehold.it/100x100", "ui-draggable"), makeImage("https://placehold.it/100x100", "ui-draggable"));
  initDrag($("#adverts-container img"));
}

function makeImage(s, c) {
  return $("<img>", {
    src: s,
    class: c
  });
}

$(document).ready(function() {
  load_draggable_images(track_page);

  $("#drop-area").sortable({
    axis: "x",
    connectWith: '.connectedSortable'
  });

  initDrag($("#adverts-container img"));

  $("#load-more-draggable-images").click(function(e) { //user clicks on button
    console.log('Button Clicked');
    track_page++; //page number increment everytime user clicks load button
    load_draggable_images(track_page); //load content
  });
});

There is an order of operations still, so it may be best to define your functions and global variable first. I removed the sortable from your first function, simply because you only have to set it once. The loading button I just made some minor changes to. And I created another function since you will be making a lot of images, why not make that a function.

Once the page has loaded and is ready, we can setup our elements. Load images, set sortable, set draggables, and finally program our click event.

So now you can pass a selector to initDrag() and the element or elements will become draggable and can be dragged into sortable. Sortable only allows x axis, so they can never be removed. You may want to consider a method for removing an image.

Upvotes: 1

Related Questions