Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Jquery UI sortable to sort 2 list at once

I have a very simple question. Using Jquery UI's sortable, I want to sort two Identical list at once. Let say I have two lists of 5 draggable objects each. Sorting one list will also sort the other list in an identical manner. Is there a way to do this with Jquery UI?

I have something like this to start...

<div class="list1">
    <div class="quote1">1</div>
    <div class="quote2">2</div>
    <div class="quote3">3</div>
    <div class="quote4">4</div>
    <div class="quote5">5</div>
</div>

<div class="list2">
    <div class="quote1">1</div>
    <div class="quote2">2</div>
    <div class="quote3">3</div>
    <div class="quote4">4</div>
    <div class="quote5">5</div>
</div>

<script>
$(function() {
    $( ".list1" ).sortable();
    $( ".list1" ).disableSelection();

    $( ".list2" ).sortable();
    $( ".list2" ).disableSelection();
});
</script>
like image 303
Yan Z Avatar asked Dec 18 '13 21:12

Yan Z


2 Answers

You can use one routine for both lists if you use IDs to identify each list, and classes to identify all lists that can be sorted.

In the jsFiddle demo, please note that change to your HTML.

jsFiddle Demo

Here is working code:

var lst, pre, post; //lst == name of list being sorted

$(".sortlist").sortable({
    start:function(event, ui){
        pre = ui.item.index();
    },
    stop: function(event, ui) {
        lst = $(this).attr('id');
        post = ui.item.index();
        other = (lst == 'list1') ? 'list2' : 'list1';
        //Use insertBefore if moving UP, or insertAfter if moving DOWN
        if (post > pre) {
            $('#'+other+ ' div:eq(' +pre+ ')').insertAfter('#'+other+ ' div:eq(' +post+ ')');
        }else{
            $('#'+other+ ' div:eq(' +pre+ ')').insertBefore('#'+other+ ' div:eq(' +post+ ')');
        }
    }
}).disableSelection();

Explanation:

  1. When you drag an item, the first thing that happens is the start: function. In there, we grab the current index position of the item and store it as pre

  2. When the item is dropped, the stop: function is executed. In here, we want to get:
    a. Which list we are sorting
    b. The NEW index position (so now we have the START position and the STOP positions)
    c. The name of the other list

  3. IF post (the NEW index position) is greater than pre (the ORIGINAL position):
    a. We are moving the item DOWN, so...
    b. When we programatically relocate the item in the other list we must use insertAfter
    ELSE
    a. We are moving the item UP in the list, so
    b. We must use the insertBefore method when moving the item in the other list.

  4. Inside the if statement, variable values tell jQuery which item to move and where to put it. It may help to see the code WITHOUT the variables. So, as an example, if I move the first item in List1 to the bottom of the list, here is what we want jQuery to do to the other list:

$('#list2 div:eq(0)').insertAfter('#list2 div:eq(4)');

Hope that helps.

like image 147
cssyphus Avatar answered Oct 02 '22 16:10

cssyphus


This solution works in real time as you are dragging:

var currentIndex;
$(function() {
    $( ".list" ).sortable({
        start: function(event, ui) { 
            currentIndex = ui.helper.index();
        },
        change: function( event, ui ) { 
            var indexCount = ui.item.parent().find('div:not(.ui-sortable-helper)');
            var sortClass = '.'+ui.item.attr('class').split(' ')[0];
            var parent = $('.list').not(ui.item.parent());
            if(currentIndex > ui.placeholder.index()){
                parent.find('div').eq(indexCount.index(ui.placeholder)).before(parent.find(sortClass));
            }
            else
                parent.find('div').eq(indexCount.index(ui.placeholder)).after(parent.find(sortClass));
            currentIndex = ui.placeholder.index();
        }
    });
    $( ".list" ).disableSelection();
});

http://jsfiddle.net/trevordowdle/EXk7T/2/

like image 40
Trevor Avatar answered Oct 02 '22 16:10

Trevor