1

This is a continuation of this question: jQuery UI Sortable, then write order into a database

The question was the following:

I want to use the jQuery UI sortable function to allow users to set an order and then on change, write it to the database and update it. Can someone write an example on how this would be done?

Since I needed to be able to reorder stuff quickly, I thought that would be very useful. There is a big problem with the accepted solution, though. I quote the answer here:

Here's a quick example that sends the data to the specified URL as soon as an element has changes position.

$('#element').sortable({
    axis: 'y',
    update: function (event, ui) {
        var data = $(this).sortable('serialize');

        // POST to server using $.post or $.ajax
        $.ajax({
            data: data,
            type: 'POST',
            url: '/your/url/here'
        });
    }
});

What this does is that it creates an array of the elements using the elements id. So, I usually do something like this:

<ul id="sortable">
   <li id="item-1"></li>
   <li id="item-2"></li>
   ...
</ul>

When you use the serialize option, it will create a POST query string like this: item[]=1&item[]=2 etc. So if you make use - for example - your database IDs in the id attribute, you can then simply iterate through the POSTed array and update the elements' positions accordingly.

For example, in PHP:

$i = 0;

foreach ($_POST['item'] as $value) {
    // Execute statement:
    // UPDATE [Table] SET [Position] = $i WHERE [EntityId] = $value
    $i++;
}

The problem with this solution is: it does not only update once every time you move an item, but it also kind of "stores" the other updates and executes them before the one you have made. So, for example, if you move 4 items, it will update 1+2+3+4 times, leading to more than possible errors and making the webpage a lot slower if you need to manage lots of items.

My question is simple: Why does that happen? How can I avoid that?

Shinra tensei
  • 1,283
  • 9
  • 21
  • 1
    Seems sort of unavoidable given your example. Because if you move the 4th item to the 1st position, your script won't just have to update the position (order) of the item that got moved, but off all the records that were before it. If that's unacceptable, then can you just turn off the AJAX requests after each element is repositioned, and instead send your form data only after the user has pressed submit? – Lucas Krupinski Aug 28 '17 at 11:24
  • Hmmm... well you're right, that seems to be a nice way to deal with this. I'll try that – Shinra tensei Aug 28 '17 at 11:48

1 Answers1

0

The answer to this is indeed very simple (thanks Lucas Krupinski). In fact, all it's needed is to add a button or something of that sort, and make it handle the updates.

Let's imagine I've added a button with onclick="save()". If we leave the code like this:

$( function() {
    $( "#sortable" ).sortable();
    $( "#sortable" ).disableSelection();
} );

function save(){
    var order = $("#sortable").sortable('serialize');
    console.log("order: " + order);
    $.ajax({
        data: order,
        type: 'POST',
        url: '/your/url/here'
    });
}

we will see that the script only executes once with the order we have right now, avoiding performance downgrade and errors in the order.

Shinra tensei
  • 1,283
  • 9
  • 21