Michael Durrant
Michael Durrant

Reputation: 96614

jquery - how to have list elements be sortable and also draggable to another list

I have two lists - A and B

I want list B to be sortable within itself. This works.
I want list A to have LI elements that can be dragged over to list B. This works.
I want list A to also be sortable within itself. This doesn't work.

It doesn't work because of the .draggable that is on list A. If I remove this it is sortable - but not not draggable to list B.

How can I have list A LI elements be both sortable within its own list and also draggable to another (sortable) list?

In my case list A is ID#list_to_process and list B is #categories. I think the question itself though is fairly generic and one that others are likely to face.

jsfiddle: http://jsfiddle.net/RNHxY/

<html>
  <head>
    <style>
    #categorizer { padding: 2px; }
    #list_to_process, #categories  { color: blue; background-color: green; border: solid; border-width: 4px }
    ul { padding: 10px; margin: 50px; float:left; list-style:none; }
    li { color: yellow; padding: 25px 80px; cursor: move; }
    li:nth-child(even) { background-color: #000 }
    li:nth-child(odd) { background-color: #666 }
  </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
    <script type="text/javascript">
      $(document).ready( function() {
        $("#categories").sortable({
          revert: true,
          receive: function(evt, ui) {
            ui.item.remove();  # Remove the item in the 'from' list.
            # Next 3 lines just there to remove empty UL when no LI's left.
            if ( $('#list_to_process li').length == 0) {
              $('#list_to_process').remove();
            }
          }
        });
        $("#list_to_process").sortable({
          revert: true  # This isn't working.
        });
        # Below is over-writing the sortable capability of #list_to_process
        $("li.to_process").draggable( {
          connectToSortable: "#categories",
          helper: "clone",
          revert: "invalid"
        });
      });
    </script>

  </head>
  <body>
    <div id="categorizer">
      <ul id="list_to_process">
        <li class="to_process" id="left1">1</li>
        <li class="to_process" id="left2">2</li>
        <li class="to_process" id="left3">3</li>
        <li class="to_process" id="left4">4</li>
        <li class="to_process" id="left5">5</li>
      </ul>
      <ul id="categories">
        <li id="righta">a</li>
        <li id="rightb">b</li>
        <li id="rightc">c</li>
        <li id="rightd">d</li>
        <li id="righte">e</li>
      </ul>
    </div>
  </body>
</html>

Upvotes: 3

Views: 1917

Answers (1)

Irvin Dominin
Irvin Dominin

Reputation: 30993

You can approach the problem by using the connectWith option:

A selector of other sortable elements that the items from this list should be connected to. This is a one-way relationship, if you want the items to be connected in both directions, the connectWith option must be set on both sortable elements.

this let you link the two list and sort elements between first list itself, first list and second list. For the second list will be sufficient the sortable feature.

Reference: http://api.jqueryui.com/sortable/#option-connectWith

The relevant script will be the following:

$("#list_to_process").sortable({
    connectWith: "#categories",
    revert: true
});

$("#categories").sortable({
    revert: true,
    receive: function (evt, ui) {
        if ($('#list_to_process li').length === 0) {
            $('#list_to_process').remove();
        }
    }
});

Here is a working fiddle: http://jsfiddle.net/IrvinDominin/JTHsU/2/

Upvotes: 2

Related Questions