Saving serialized sortable data from jQuery / ajax using Laravel 4+

Having a problem finding the best way to store the ajax sorted list in my database. I am using HTML5Sortable and Laravel 4.2 framework. The main end result I'm trying to achieve is for the user to be able to click and drag the list items and reorder them and this new order will be saved in the database in a field called "order" so that a new one will appear on the page later on return order.

I have a list of chapters on a page, for example:

<ul class="sortable">
    @foreach ($chapters as $chapter)
      <li class="ui-state-default" data-order="{{ $chapter->order }}">{{ $chapter->title }}</li>
    @endforeach
</ul>

      

And I can drag and drop them using HTML5Sortable and then serialize this data and send it via ajax POST which fires every time the list is reordered like this:

$('.sortable').sortable().bind('sortupdate', function(e, ui) {

    var order = $('ul.sortable li').map(function(){ 
        return $(this).data("order");
    }).get();

    var uuid = "<?php echo$uuid; ?>";

    $.ajax({
        type: "POST",
        url: "api-ch-order",
        dataType: "json",
        data: {order: order, uuid: uuid},
        success: function(order){
          console.log(order)
        }
    });
});

      

My controller in / api -ch-order receives data and stores the new order:

if(Request::ajax()){

  $uuid = Input::get('uuid');
  $order = Input::get('order');

  $i = 1;

  foreach($order as $position) {

    $chapter = Chapter::where('book_uuid', $uuid)->where('order', $position)->first();

    $chapter->order = $i;
    $chapter->save();

    $i++;

  }

}

      

PROBLEM

The problem I am running into is that it doesn't work in some cases, the loop is causing problems.

eg.

LOOP 1: FIND Chapter where order = 2 and change the order to 1

LOOP 2: FIND Chapter where order = 1 and change it to 2

The problem here is that in LOOP 2 it finds the result of LOOP 1 and updates that instead ... I guess ... This problem is a little confusing to me ... But I'm 99% sure that the foreach loop in my controller is problem and I'm not sure what is the best way to fix this.

Resources to link to this question:

ANSWER!!!

As indicated in r4xz, the answer is to use the identifier as a constant.

eg.

Html

<ul class="sortable">
    @foreach ($chapters as $chapter)
      <li class="ui-state-default" data-id="{{ $chapter->id }}">{{ $chapter->title }}</li>
    @endforeach
</ul>

      

Js

$('.sortable').sortable().bind('sortupdate', function(e, ui) {

    var id = $('ul.sortable li').map(function(){ 
        return $(this).data("id");
    }).get();

    var uuid = "<?php echo$uuid; ?>";

    $.ajax({
        type: "POST",
        url: "api-ch-order",
        dataType: "json",
        data: {id: id, uuid: uuid},
        success: function(order){
          console.log(id)
        }
    });
});

      

PHP CONTROLLER

if(Request::ajax()){

  $uuid = Input::get('uuid');
  $id = Input::get('id');

  $i = 1;

  foreach($id as $val) {

    $chapter = Chapter::where('id', $val)->first();

    $chapter->order = $i;
    $chapter->save();

    $i++;

  }

}

      

+3


source to share


2 answers


The most common solution is to store the ID of the location and object:

<li data-id="{{ $chapter->id }}" data-order="{{ $chapter->order }}">{{ $chapter->title }}</li>

      



Then, in the controller, you simply use:

UPDATE chapter SET order = $order WHERE id = $id

      

+2


source


This question was very helpful and introspective! GREAT! Thank!

Just for those who are not using the same structure in my case. This is what I did:



public function myRouteFunction(Request $request)
    foreach($ids as $key => $id) {
        $update = DB::table('mybase')->where('id', $id)->update(['sort_order' => $key]);
    }
}

      

Maybe this can help someone :)

0


source







All Articles