skip to Main Content

I’m trying to make a sortable table in my laravel app where the order also needs to be updated in the database, I’m trying to do it with jquery, ajax.

I tried to figure it out with this pieces of code:

JQuery/Ajax

$(document).ready(function () {
        $('table tbody').sortable({
            update: function (event, ui) {
                $(this).children().each(function (index) {
                    if ($(this).attr('data-position') != (index + 1)) {
                        $(this).attr('data-position', (index + 1)).addClass('updated');
                    }
                });

                saveNewPositions();
            }
        });
    });

    function saveNewPositions() {
        var positions = [];
        $('updated').each(function () {
            position.push([$(this).attr('data-index'), $(this).attr('data-position')]);
            $(this).removeClass('updated');
        });

        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });

        $.ajax({
            url: 'cursos',
            method: 'POST',
            dataType: 'text',
            data: {
                'updated': 1,
                'positions': positions,
                '_token': '{{ csrf_token() }}'
            },
        })

Then in my web.php I created a post route:

Route::post('/cursos', function (Request $request){
return SectionCourseController::updateOrder($request);})->name('post');

In my controller I created this function:

        public static function updateOrder(Request $request)
{
    var_dump($request->positions);
    foreach ($request->positions as $position) {
        $index = $position[0];
        $newPosition = $position[1];
        $seccion = SectionCourse::findOrFail($index);
        $seccion->order = $newPosition;
        $seccion->save();
    }

    return response('success', 200);
}

When I’m trying to update the order, I’m having an error on the console of 500 (Internal Server Error).

[2022-06-14 14:16:18] local.ERROR: foreach() argument must be of type array|object, null given {"userId":1,"exception":"[object] (ErrorException(code: 0): foreach() argument must be of type array|object, null given

Sorry if I’m doing something bad on Ajax, this is the first time I try to do something on it.

3

Answers


  1. There is 2 cases for 500 internal server error

    1. you had not put the {csrf} token there when sending request through ajax.
    2. Use new FormData() object while sending response through ajax and use these params with processData: false,contentType: false,type: ‘POST’
    Login or Signup to reply.
  2. I’ve done something very similar to this, so as I see it right now you are firstly missing a csrf token, so in the view add this below the code where you declare the $(‘updated’) each.

    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
    
    $.ajax({
        method: 'POST',
        dataType: 'json',
        url: 'cursos', // No {{}} needed here
        data: {
            update: 1,
            orders: orders,
             _token: '{{ csrf_token() }}'
         },
    });
    

    Next your controller is a mess. So rewrite it to fit at least some of laravels writing standards. Something like this

    public function updateOrder(Request $request)
    {
        foreach ($request->positions as $position) {
            $index = $position[0];
            $newPosition = $position[1];
            $seccion = SectionCourse::findOrFail($index);
            $seccion->order = $newPosition;
            $seccion->save();
        }
    
        return response('success', 200);
    }
    

    Also add the following when declaring .sortable

    axis: 'y',
    containment: 'parent',
    update: ...
    
    Login or Signup to reply.
  3. Add a meta-tag to each page, or master layout

         <meta name="csrf-token" content="{{ csrf_token() }}"> and add to your js page
    
     $.ajaxSetup({
      headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
      }
    
    });
    

    Dont forget to add data inside

    $.ajax({
    url: "test",
    type:"POST",
    data: { '_token': token, 'someOtherData': someOtherData },
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search