Sortable: Saving the sorted position in Database

Created on 6 Sep 2017  路  9Comments  路  Source: SortableJS/Sortable

Hi RubaXa,

It's very good plugin. I am using your plugin in WordPress. Can you please let me know how can I save the elements positions in Database. I have seen the issue regarding local storage. I think it's not a good approach. I just want to save positions in the database and display the positions according to the database.

Your help or any glimpse will be much appreciated.

Thanks again for good work.

Regards,
Abdullah
@WPPluginDev

Most helpful comment

Hello @ashucg,

I have managed to get the track record of the both lists while dragging or dropping an element between the lists.

var element = $('#foo')[0]; var sortable = new Sortable(element, { group: "words", //ghostClass: 'drag-ghost', onSort: function (e) { var items = e.to.children; var result = []; for (var i = 0; i < items.length; i++) { result.push($(items[i]).data('id')); } console.log(result); /* Do ajax call here */ } }); var element1 = $('#bar')[0]; var sortable1 = new Sortable(element1, { group: "words", //ghostClass: 'drag-ghost', onSort: function (e) { var items = e.to.children; var result = []; for (var i = 0; i < items.length; i++) { result.push($(items[i]).data('id')); } console.log(result); /* Do ajax call here */ } });

Thank you so much for your help.

Best Regards,
Abdullah
@wpplugindev

All 9 comments

Hi @abdullah1908

I would suggest you to do the following:

  • Add data-value="<SOME_VALUE>" attribute to <li> tags.
  • Use onSort event (if you are not using some other event to POST the data) to create an object like {<INDEX_OF_LI> : <SOME_VALUE>}.
  • After that, POST the data using AJAX and store it in your WP DB.

Note: <SOME_VALUE> is the value that you want to store in your DB and <INDEX_OF_LI> is the index of <li> elements within the parent <ul> element

Hello @ashucg ,

Thanks for your help. I already did this and saved the data through _data-id_ attribute. But I want to display elements position physically on the basis of their last drag & drop saved position in DB.

Thanks again for your help.

Regards,
Abdullah
@wpplugindev

Hello @abdullah1908 ,

I have done this in past, not in WP though, but it was simple. This is how managed to do that:

  • I stored the values in an array in PHP, structured as [index1 => value1, index2 => value2,....., indexN => valueN], this was the initial value (when no value was stored in the DB) and lets call it $list_order_value. Every time I checked if there was any value stored in the DB
  • I then used this array to print the required HTML. If you have more values, you can use an array for value, the main point here is the index.
  • When the order was changed to something else, I used to sent the updated index values (relative to the <ul>). Lets say the new indexes are in the following order: index2, index1,...., indexN
  • Simply sorted the $list_order_value array according to the updated indexes.
  • Final array became: `[index2 => value2, index1 => value1,....., indexN => valueN]. I then converted this to JSON string and store that value in the DB.

Hope this gives you some idea.

Happy coding!

Hello @ashucg,

Actually, I have two lists and move the element from left to right or right to left as well as top to bottom. In the single list, it's easy to save the drag & drop position and print HTML structure as well. But in my case, I have to manage left to right or right to left movement with their prospective positions too.

I am also sharing a screenshot URL of my UI as well as my working code.
http://prntscr.com/gk7tkk

(function ($) {
    'use strict';
    $(document).ready(function () {
        var byId = function (id) {
            return document.getElementById(id);
        };
        if (!console.log) {
            console.log = function () {
                alert([].join.apply(arguments, ' '));
            };
        }
        Sortable.create(byId('foo'), {
            group: "words",
            animation: 150,
            dataIdAttr: 'data-id',
            draggable: '.item',
            store: {
                get: function (sortable) {
                    var order = localStorage.getItem(sortable.options.group);
                    return order ? order.split('|') : [];
                },
                set: function (sortable) {
                    var order = sortable.toArray();
                    console.log(order, 'foooooooooooooooooooooooo');
                    $('.visuaplayoutCol01').attr('value', order);
                }
            },
            onEnd: function (/**Event*/evt) {
                console.log(evt.item.dataset.id, 'datasetID');  // element's new index within parent
                var order = sortable.toArray();
                $('.visuaplayoutCol02').attr('value', $('.visuaplayoutCol01').attr('value') + ',' + evt.item.dataset.id);
            },
            onAdd: function (/**Event*/evt) {
                var itemEl = evt.item;  // dragged HTMLElement
                console.log(evt.from, 'From');  // previous list
                console.log(evt.to, 'To');  // next list
                //$('.visuaplayoutCol02').attr('value', $('.visuaplayoutCol01').attr('value') + ',' + evt.item.dataset.id);
            },
            onUpdate: function (evt) {
                var itemEl = evt.item;  // dragged HTMLElement
                console.log(itemEl, 'draggedelement');
            },
            onSort: function (evt) {
                var itemEl = evt.item;  // dragged HTMLElement
                console.log(itemEl, 'onSort');
            },
        });


        Sortable.create(byId('bar'), {
            group: "words",
            animation: 150,
            dataIdAttr: 'data-id',
            draggable: '.item',
            store: {
                get: function (sortable) {
                    var order = localStorage.getItem(sortable.options.group);
                    return order ? order.split('|') : [];
                },
                set: function (sortable) {
                    var order = sortable.toArray();
                    console.log(order, 'baaaaaaaaaaaaaaaaaaaaaaaaar');
                    $('.visuaplayoutCol02').attr('value', order);
                }
            },
            onEnd: function (/**Event*/evt) {
                $('.visuaplayoutCol01').attr('value', $('.visuaplayoutCol02').attr('value') + ',' + evt.item.dataset.id);
            },
            onAdd: function (/**Event*/evt) {
                var itemEl = evt.item;  // dragged HTMLElement
                console.log(evt.from, 'From');  // previous list
                console.log(evt.to, 'To');  // next list
            },
            onUpdate: function (evt) {
                var itemEl = evt.item;  // dragged HTMLElement
                console.log(itemEl);
            },
            onSort: function (evt) {
                var itemEl = evt.item;  // dragged HTMLElement
                console.log(itemEl, 'onSort');
            },
        });

    });
})(jQuery);

Thanks again for your help.

Regards,
Abdullah
@wpplugindev

Hello @ashucg,

Here is also the JS Fiddle link for the updated code. Actually, I want to get the track record for the list where I am dropping the element.
https://jsfiddle.net/wpplugindev/53vhp34e/22/

Thanks again for your help.
Regards,
Abdullah
@wpplugindev

Hello @ashucg,

I have managed to get the track record of the both lists while dragging or dropping an element between the lists.

var element = $('#foo')[0]; var sortable = new Sortable(element, { group: "words", //ghostClass: 'drag-ghost', onSort: function (e) { var items = e.to.children; var result = []; for (var i = 0; i < items.length; i++) { result.push($(items[i]).data('id')); } console.log(result); /* Do ajax call here */ } }); var element1 = $('#bar')[0]; var sortable1 = new Sortable(element1, { group: "words", //ghostClass: 'drag-ghost', onSort: function (e) { var items = e.to.children; var result = []; for (var i = 0; i < items.length; i++) { result.push($(items[i]).data('id')); } console.log(result); /* Do ajax call here */ } });

Thank you so much for your help.

Best Regards,
Abdullah
@wpplugindev

When first initializing the script, it automatically re-sorts the list. Is there any way to either disable this or specify the initial order?

I am looking for the same. I have an initial order coming from server that was saved previously by serializing the order from sortable.toArray(). Is there an easy way in the library to set this order on initialization (short of manually sorting dom some other way)? Library seems to be able to this for its store feature, but is this exposed as an initialization option or a method?

something like initialOrder:['id1',id3','id2'...] will be very useful.

I am looking for the same. I have an initial order coming from server that was saved previously by serializing the order from sortable.toArray(). Is there an easy way in the library to set this order on initialization (short of manually sorting dom some other way)? Library seems to be able to this for its store feature, but is this exposed as an initialization option or a method?

something like initialOrder:['id1',id3','id2'...] will be very useful.

Hi,

Just initialized <li> element with "data-id" attribute

<ul id="sortable2" class="connectedSortable">
  <li data-id="1" class="ui-state-highlight">Item 1</li>
  <li data-id="2" class="ui-state-highlight">Item 2</li>
  <li data-id="3" class="ui-state-highlight">Item 3</li>
  <li data-id="4" class="ui-state-highlight">Item 4</li>
  <li data-id="5" class="ui-state-highlight">Item 5</li>
</ul> 

Was this page helpful?
0 / 5 - 0 ratings