Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change dynamic status with x-editable in laravel

I have select button where I choose status for my entries. This status comes from statuses table and it's not a column in each table (it's general option). What I want to do is to change status_id column in my tables with help of x-editable but I don't know how to get my dynamic data in JavaScript.

Here is my current form to show statuses in index page of my reviews for example:

 <form action="{{route('updatebyajax', $rating->id)}}" method="post">
    {{csrf_field()}}
       <td class="text-center" style="width:100px;">
          <select class="form-control status" name="status_id">
            @foreach($statuses as $status)
              <option id="rating" class="rating" data-url="{{ route('updateratebyajax', $rating->id) }}" data-pk="{{ $rating->id }}" data-type="select" data-placement="right" data-title="Edit Rate" value="{{$status->id}}">{{$status->title}}</option>
           @endforeach
        </select>
    </td>
 </form>

So what I need is basically get info out of statuses table and change by select.

dropdown

Update

As requested here is my table screenshot:

table image

PS: here is default sample of select button: sample link

<a href="#" id="status" data-type="select" data-pk="1" data-url="/post" data-title="Select status"></a>
<script>
$(function(){
    $('#status').editable({
        value: 2,    
        source: [
              {value: 1, text: 'Active'},
              {value: 2, text: 'Blocked'},
              {value: 3, text: 'Deleted'}
           ]
    });
});
</script>

Update 2

Review Database reviews

Status Table status

Update 3

I just add my controller method and route in case

controller

public function updatebyajax(Request $request, $id)
  {
    return Rating::find($id)->update([
      'status_id' => $request->get('status_id'),
    ]);
  }

route

Route::post('/updatebyajax/{id}', 'RatingController@updatebyajax')->name('updatebyajax');

UPDATE 4

I mixed several solutions on internet till I finally get status 200 OK in my network but still nothing changes in my database, here is my current codes:

controller

public function updatebyajax(Request $request, $id)
  {
    if (request()->ajax())
        {
            $ratings = DB::table('ratings')->select('status_id','id')->where('status_id', '=', $id)->get();
            return Response::json( $ratings );
        }
  }

AJAX

<script type="text/javascript">
$(".status").change(function() {
    $.ajax({
        type: "post", // for edit function in laravel
        url: "{{url('admin/updatebyajax')}}" + '/' + $(this).val(), // getting the id of the data
        data: {_token: "{{ csrf_token() }}",status: this.value }, //passing the value of the chosen status
        dataType: 'JSON',
        success: function (data) {
            console.log('success');
        },
        error: function (data) {
            console.log('error');
        }
    });
});
</script>

FORM

<form action="{{route('updatebyajax', $rating->id)}}" method="post">
                             {{csrf_field()}}
                              <td class="text-center" style="width:100px;">
                                <select id="{{ $rating->id }}" class="form-control status" name="status_id">
                                  @foreach($statuses as $status)
                                    <option value="{{$status->id}}">{{$status->title}}</option>
                                  @endforeach
                                </select>
                              </td>
                          </form>

UPDATE 5

Regarding to leih answer currently I have this:

Controller

public function updatebyajax(Request $request, $id)
  {
    // Note: should probably use a $request->has() wrapper to make sure everything present

    try {
        // you can also use the ID as a parameter, but always supplied by x-editable anyway
        $id = $request->input('pk');
        $field = $request->input('name');
        $value = $request->input('value');

        $rating = Rating::findOrFail($id);
        $rating->{$field} = $value;
        $rating->save();
    } catch (Exception $e) {
        return response($e->getMessage(), 400);
    }
  }

Route

Route::post('/updatebyajax', 'RatingController@updatebyajax')->name('updatebyajax');

Blade

//Select
<a
  href="#"
  class="status"
  data-type="select"
  data-pk="{{ $rating->id }}"
  data-value="{{ $rating->status_id }}"
  data-title="Select status"
  data-url="{{ route('updatebyajax') }}"
></a>

//JS

<script type="text/javascript">

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

$(function() {
    $('.status').editable({
      type:"select",
        source: [
            @foreach($statuses as $status)
                { value: {{ $status->id }}, text: {{ $status->title }} }
            @endforeach
        ],
    });
});
</script>

And here is the result I get:

screenshot5

PS: If I don't use $.ajaxSetup({ headers: {.... and use java code in answer I will get this error

Parse error: syntax error, unexpected ','

Any idea??

like image 566
mafortis Avatar asked Dec 12 '17 00:12

mafortis


2 Answers

When using X-edtiable with a <select> option, it's good to look at the documentation, but better to look at official examples and check the FAQ for what the back end needs. You don't need to make your own forms or write your own AJAX requests with X-editable (that's the whole point). Based on what you're asking, it sounds like the code should look similar to this:

RatingController

public function UpdateByAjax(Request $request)
{
    // Note: should probably use a $request->has() wrapper to make sure everything present

    try {
        // you can also use the ID as a parameter, but always supplied by x-editable anyway
        $id = $request->input('pk');
        $field = $request->input('name');
        $value = $request->input('value');

        $rating = Rating::findOrFail($id);
        $rating->{$field} = $value;
        $rating->save();
    } catch (Exception $e) {
        return response($e->getMessage(), 400);
    }

    return response('', 200);
}

Route

Route::post('/updatebyajax', 'RatingController@UpdateByAjax')->name('updatebyajax');

View

Note: I'm not setting the CSRF token below as it should already be set globally for X-editable (e.g. for text fields in screenshot) if required, or via some other mechanism.

<a
  href="#"
  class="status"
  data-type="select"
  data-pk="{{ $rating->id }}"
  data-name="status_id"
  data-value="{{ $rating->status_id }}"
  data-title="Select status"
  data-url="{{ route('updatebyajax') }}"
></a>
<script>
$(function() {
    // using class not id, since likely used with multiple records
    $('.status').editable({
        // Note: cleaner to format in the controller and render using the @json directive
        source: [
            @foreach($statuses as $status)
                { value: '{{ $status->id }}', text: '{{ $status->title }}' }
                @unless ($loop->last)
                    ,
                @endunless
            @endforeach
        ]
    });
});
</script>

Additional reference: see 'Rendering JSON' in the Displaying Data blade documentation

like image 78
Leith Avatar answered Oct 18 '22 05:10

Leith


I think this would be useful for you.

  • Put the id of the value that you want to change in the id of the select box
  • ajax function in jquery

    $(".status").change(function() {
        $.ajax({
            type: "PUT", // for edit function in laravel 
            url: "{{url('updatebyajax')}}" + '/' + this.id, // getting the id of the data 
            data: {_token: "{{ csrf_token() }}",status: this.value }, //passing the value of the chosen status
            dataType: 'JSON',
            success: function (data) {
                // some kind of alert or console.log to confirm change of status
            },
            error: function (data) {
                // error message
            }
        });
    });
    

Hope it helps

like image 44
Miggy Avatar answered Oct 18 '22 07:10

Miggy