Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Laravel 5 inplace editing using jquery's x-editable plugin . Inline and bulk editing examples.
/**
*
* In this example we create view with inplace and bulk editing.
* Tools and plugins:
* jQuery
* xEditable jquery plugin
* twitter bootstrap
*
*/
/*--------------------------------------------------------------------------------*/
//1. create 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']);
/*--------------------------------------------------------------------------------*/
//2. Create migration.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
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');
}
}
/*--------------------------------------------------------------------------------*/
//2a.
//Run migration using command:
//php artisan migrate
//Add some data to db.
/*--------------------------------------------------------------------------------*/
//3. Create model Test.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class test extends Model
{
protected $fillable = [
'name',
'value',
'date'
];
}
/*--------------------------------------------------------------------------------*/
//4. create controller (TestCpntroller):
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Test;
use Input;
use Schema;
use 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')
->with('test', $test)
->with('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);
}
}
/*--------------------------------------------------------------------------------*/
//5. create view in resources/views/test/index.blade.php
@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
/*--------------------------------------------------------------------------------*/
//6. create view in resources/views/app.blade.php
<!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>
@rameshguthulakkd

This comment has been minimized.

Copy link

commented Jan 10, 2017

sdfdfsdfsdf

@jimbomilk

This comment has been minimized.

Copy link

commented Jan 29, 2017

Thank you very much!!! It helps me a looot!!!

Just a little comment : I got an error about csrf. If anyone has the same problem, add this to fix it:

At the top of the view , add:

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

And add a additional parameter with the token in JS:

$('.fastEdit').editable({
        params: function(params) {
            // add additional params from data-attributes of trigger element
            params._token = $("#_token").data("token");
            params.name = $(this).editable().data('name');
            return params;
        },

.....

This will fix the issue about CSRF.

Regards!

@nathansiafa

This comment has been minimized.

Copy link

commented Jun 28, 2017

How do you apply server side validations? I have tried but laravel validation method doesn't seem to validate the x-editable request coming in. I think it's because x-editable sends an array instead of an object. I posted a thread on Stack Overflow concerning he issue, but haven't gotten any response. Can you please help me? https://stackoverflow.com/questions/44780698/how-to-validate-x-editable-request-in-laravel-server-side

@hondaman900

This comment has been minimized.

Copy link

commented Feb 23, 2018

Thank you for this great example, it's the best available for implementing x-editable fields in Laravel. I had to do some tweaking for Laravel 5.5 but it works great.

As a follow-up question, I want to have another column in the table that shows a math calc on the editable field value, so that when the user edits it, the calculated field also changes. In the above example, I added a column after the value using <td>{{$t->value/2}}</td> . This works great to show half the value, but my question is how do I get this field to calculate dynamically when the user changes the x-editable value?

Thanks in advance

:: UPDATE ::

Well, I found my own answer by trial and error and experimenting with DOM elements and the x-editable parameter. I assigned an ID to my table cell so that I could reference it, using the index value in the example, like so:

<td id="result_{{$t->id}}">{{$t->value/2}}</td>

Then in the x-editable javascript I added a success function as it's the only way that I can see to get the changed value back from the x-editable element. I used that function to put the new calculated value into the corresponding table element using the new ID, like so:

        success:function(response, newValue){
            document.getElementById("result_"+$(this).attr('data-pk')).innerHTML = (newValue/2);
        },

It now works great with the new value updating every time the x-editable value is changed. Hope this helps someone else.

:: UPDATE 2 ::

The following code isolates the processing of the update value to the numeric "value" column. Without this, editing the "name" column triggers the success function and an attempt to do math on the name string, resulting in a NaN error. This IF statement prevents that:

        success:function(response, newValue){
            if ($(this).editable().data('name') == "value"){
                document.getElementById("result_"+$(this).attr('data-pk')).innerHTML = (newValue/2);
            }
        },
@kirubha7

This comment has been minimized.

Copy link

commented Feb 15, 2019

sdfdfsdfsdf

ldfj ghadfkjbga

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.