laravel 5.3 x-editable table bulk is updating, sin

2019-09-06 16:41发布

I have implemented this example by Papadupa verbatum that illustrates bulk editing and row editing (column in line and column pop-up):
https://gist.github.com/pupadupa/4b8e8a9a3a466720bad8

The bulk updating works just fine, but the inline row field editing does not, and reports an internal server error (500):
jquery.js:8625 localhost:8000/test/update/1 500 (Internal Server Error)

x-editable table row edit error

Here is papadupa's implementation:

Test Table - you do need to add a couple of rows to the test table after the table is created so there are updatable rows available:

`class CreateTestsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tests', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
            $table->string('name')->nullable();
            $table->float('value')->nullable();
            $table->date('date')->nullable();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tests');
    }
}`

The Controller:

`namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Test;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;

class TestController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        $test = Test::select()
            ->orderBy('id')
            ->get()
        ;

        // $test_columns = Schema::getColumnListing('tests');
        $test_model = new Test();
        $fillable_columns = $test_model->getFillable();
        foreach ($fillable_columns as $key => $value) {
            $test_columns[$value] = $value;
        }
        return view('test.index',[
            'test'=>$test,
            'test_columns'=>$test_columns,
        ]);
    }

    public function update(Request $request, $id)
    {
        $test = Test::find($id);
        $column_name = Input::get('name');
        $column_value = Input::get('value');

        if( Input::has('name') && Input::has('value')) {
            $test = Test::select()
                ->where('id', '=', $id)
                ->update([$column_name => $column_value]);
            return response()->json([ 'code'=>200], 200);
        }

        return response()->json([ 'error'=> 400, 'message'=> 'Not enought params' ], 400);
    }



    public function bulk_update(Request $request)
    {
        if (Input::has('ids_to_edit') && Input::has('bulk_name') && Input::has('bulk_value')) {
            $ids = Input::get('ids_to_edit');
            $bulk_name = Input::get('bulk_name');
            $bulk_value = Input::get('bulk_value');
            foreach ($ids as $id) {
                $test = Test::select()
                    ->where('id', '=', $id)
                    ->update([$bulk_name => $bulk_value]);
            }
            // return Redirect::route('client/leads')->with('message', $message);
            $message = "Done";
        } else {
            $message = "Error. Empty or Wrong data provided.";
            return Redirect::back()->withErrors(array('message' => $message))->withInput();
        }
        return Redirect::back()->with('message', $message);
    }

}`

The Routes:

    `
       Route::get('test', ['uses' => 'TestController@index']);
        Route::post('test/update/{id}', ['as' => 'test/update', 'uses' => 'TestController@update']);
        Route::post('test/bulk_update', ['as' => 'test/bulk_update', 'uses' => 'TestController@bulk_update']);
    `

The /test/index.blade.php file:

`@extends('app')
@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-12">
                @if (count($errors) > 0)
                    <div class="alert alert-danger">
                        Oops! We have some erros
                        <ul>
                            @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                            @endforeach
                        </ul>
                    </div>
                @endif
                @if(Session::has('message'))
                    <div class="alert alert-success">
                        {!!Session::get('message')!!}
                    </div>
                @endif
            </div>
        </div>

        <div class="row">
            <div class="col-md-12">

                <h2>Bulk edit</h2>
                {!! Form::open(['action' => 'TestController@bulk_update', 'method' => "POST", "class"=>"form-inline"]) !!}
                <div class="form-group">
                    <label for="lead_status">For selected rows change filed </label>
                    {!! Form::select('bulk_name', $test_columns, [], ['class' => 'form-control']) !!}
                </div>
                <div class="form-group">
                    <label for="lead_status">equal to</label>
                    {!! Form::text('bulk_value', null, ['class' => 'form-control'])!!}
                </div>
                <button class="btn btn-default">Save</button>
                <hr>
                <table class="table table-striped">
                    @foreach($test as $t)
                        <tr>
                            <td><td width="10px"><input type="checkbox" name="ids_to_edit[]" value="{{$t->id}}" /></td></td>
                            <td>{{$t->id}}</td>
                            <td><a href="#" class="testEdit"
                                   data-type="text" data-column="name"
                                   data-url="{{route('test/update', ['id'=>$t->id])}}"
                                   data-pk="{{$t->id}}" data-title="change" data-name="name">{{$t->name}}</a></td>
                            <td><a href="#" class="testEdit"
                                   data-type="text" data-column="value"
                                   data-url="{{route('test/update', ['id'=>$t->id])}}"
                                   data-pk="{{$t->id}}" data-title="change" data-name="value">{{$t->value}}</a></td>
                            <td><a href="#" class="testEdit"
                                   data-type="text" data-column="date"
                                   data-url="{{route('test/update', ['id'=>$t->id])}}" data-pk="{{$t->id}}" data-title="change" data-name="date">{{$t->date}}</a></td>
                        </tr>
                    @endforeach
                </table>
                {!! Form::close() !!}


            </div>
        </div>
    </div>
@endsection
@section('scripts')
    <script>
        $.fn.editable.defaults.mode = 'inline';
        $(document).ready(function() {
            $('.testEdit').editable({
                params: function(params) {
                    // add additional params from data-attributes of trigger element
                    params.name = $(this).editable().data('name');
                    return params;
                },
                error: function(response, newValue) {
                    if(response.status === 500) {
                        return 'Server error. Check entered data.';
                    } else {
                        return response.responseText;
                        // return "Error.";
                    }
                }
            });
        });
    </script>
@endsection`

and the app.blade file:

`!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>xEditable and laravel 5. Inline and bulk editing examples.</title>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <!-- Fonts -->
    <link href='//fonts.googleapis.com/css?family=Roboto:400,300' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
@yield('content')
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
@yield('scripts')
</body>
</html>
`

I am running Laravel 5.3 and I do not know which laravel version pupadupa used. My original objective is to be able to implement laravel 5.3 inline table editing using eloquent Model. X-editable seems to be a perfect fit, if I can just get it to work.

Papadupa's example is terrific because it simplifies the coding to edit any xeditable column in a table row. I don't believe this is an x-crsf issue because the 'bulk_update' function works for the the same table and form using the script for x-editable. It appears the single row update is not updating the database so there is no valid response coming back

1条回答
叛逆
2楼-- · 2019-09-06 17:09

SOLVED!! It was a x-csrf issue:

I added this to the view (app.blade.php):

 ` <div id="_token" class="hidden" data-token="{{ csrf_token() }}"></div>`

and added another param to the script section:

 `params._token = $("#_token").data("token");`

Interesting that the bulk_update function worked without this x-csrf inclusion. I remain curious as to why . . .

查看更多
登录 后发表回答