7
votes

I have two sortable lists which hold work orders. The second list is a Route while the first is just a list of all the work orders that haven't been added to the Route list. The idea is that the user drags work orders into the Route in a specific order, rearranging the work orders to create a route that the employee will follow.

My problem is with managing the position of new work orders dragged onto the Route list. Is there an easy way to deal with updating the positions of all of the list items (on the database side of things via ajax calls) as new items are being added?

A bit more info for clarity...

When the Route list is empty (no work orders added yet) it is simple - user drags new work order onto empty list, ajax call made to save the details (on the underlying records on the server) of both the Route object and the Route Item just added.

When the user drags the second work order into the Route list I want to determine if the new work order will become first in the list, or second, then update all the information (server side) accordingly for all items in the list. Things get really complicated when I want to add a new work order to a Route that already has like 30 work orders.

Is there a simple way to do this or is it just a matter of coding up a decent amount of jQuery and backend functions to manage this? I have been hunting around the net for solutions but can't find anything all that definitive.

2
How do you know where a work order is supposed to go in the route?Explosion Pills

2 Answers

8
votes

You can save order of each column every time there is an update using an ajax call. Working JSFiddle Example

Explanation below: For this to work you need to give each of the sort able items an unique id. For example:

    <ul id="sortable1" class="connectedSortable">
    <li class="ui-state-default" id='item1'>Item 1</li>
    <li class="ui-state-default" id='item2'>Item 2</li>
    <li class="ui-state-default" id='item3'>Item 3</li>
    <li class="ui-state-default" id='item4'>Item 4</li>
    <li class="ui-state-default" id='item5'>Item 5</li>
   </ul>
    <ul id="sortable2" class="connectedSortable">
        <li class="ui-state-highlight" id='item6'>Item 6</li>
        <li class="ui-state-highlight" id='item7'>Item 7</li>
        <li class="ui-state-highlight" id='item8'>Item 8</li>
        <li class="ui-state-highlight" id='item9'>Item 9</li>
        <li class="ui-state-highlight" id='item10'>Item 10</li>
    </ul>

Then you can capture the id of each sortable li and return post that in a ajax request.

 $(function () {
     $("#sortable1, #sortable2").sortable({
         connectWith: ".connectedSortable",
         update: function () {
             var order1 = $('#sortable1').sortable('toArray').toString();
             var order2 = $('#sortable2').sortable('toArray').toString();

             alert("Order 1:" + order1 + "\n Order 2:" + order2); //Just showing update
             $.ajax({
                 type: "POST",
                 url: "/echo/json/",
                 data: "order1=" + order1 + "&order2=" + order2,
                 dataType: "json",
                 success: function (data) {


                 }
             });

         }
     }).disableSelection();
 });

You can then doing the process to save the order on the page you are doing the requesting on.

4
votes

Is there a simple way to do this or is it just a matter of coding up a decent amount of jQuery and backend functions to manage this? I have been hunting around the net for solutions but can't find anything all that definitive.

Pretty much yes, but if you already know how to handle Ajax calls for sortables then mixing two lists is not an issue. I am using a modified version of the coding on this page. And I am using the receive event & the stop event to show how you can hook simple function into the basic sortable coding:

<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>jQuery UI Sortable - Connect lists</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
  <script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
  <link rel="stylesheet" href="/resources/demos/style.css" />
  <style>
  #sortable1, #sortable2 { list-style-type: none; margin: 0; padding: 0 0 2.5em; float: left; margin-right: 10px; }
  #sortable1 li, #sortable2 li { margin: 0 5px 5px 5px; padding: 5px; font-size: 1.2em; width: 120px; }
  </style>
  <script>
  $(function() {
    $( "#sortable1, #sortable2" ).sortable({
      connectWith: ".connectedSortable",
      receive: function( event, ui ) { alert('Receive!'); },
      stop: function( event, ui ) { alert('Stop!'); }
    }).disableSelection();
  });
  </script>
</head>
<body>

<ul id="sortable1" class="connectedSortable">
  <li class="ui-state-default">Item 1</li>
  <li class="ui-state-default">Item 2</li>
  <li class="ui-state-default">Item 3</li>
  <li class="ui-state-default">Item 4</li>
  <li class="ui-state-default">Item 5</li>
</ul>

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


</body>
</html>

So when an item is sorted and the sorting stops, a 'Stop!' alert box pops up. And when a new item is dragged into one list from another a 'Receive!' alert box pops up in addition to the stop. You might be able to just use the stop event to trigger an Ajax call, but the receive even can be useful to do something else if/when a new item is added to a list.