Create ajax CRUD, search, sort and pagination with Laravel 5.5

Published Date: 25-Nov-2017 | Tags: Laravel 5.5  Bootstrap 4  Ajax  CRUD  

This tutorial I want to show you how to create a complete CRUD, search, sort and pagination operations without refreshing page with Laravel 5.5 and JQuery Ajax.

Suppose that your server is running on port 80 and your project folder is /demo.

Note

  • I use laravelcollective to create form. So please install laravelcollective if you not yet install it. You can visit here for the installation guide.
  • I use bootstrap 4 for my UI, so please check bootstrap if you are new to bootstrap.

 

Step 1: Create Database Table

 Create table customers with structure as below.

customer table structure

 

Step 2: Database Configuration

Edit this file /demo/.env and update your database name, username and password.

Suppose that your database name is demo, username is root, and password is empty.

laravel db config

 

Step 3: Add Route

Add these lines to file /demo/routes/web.php.

Route::group(['prefix' => 'laravel-crud-search-sort-ajax'], function () {
    Route::get('/', 'Crud3Controller@index');
    Route::match(['get', 'post'], 'create', 'Crud3Controller@create');
    Route::match(['get', 'put'], 'update/{id}', 'Crud3Controller@update');
    Route::delete('delete/{id}', 'Crud3Controller@delete');
});

 

Step 4: Create Model

Create model file Customer.php in /demo/app.

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{

}

 

Step 5: Create Ajax Javascript File

Create js file ajax-crud.js in /demo/public/js. (create folder js if it does not exist).  

$(document).on('click', 'a.page-link', function (event) {
    event.preventDefault();
    ajaxLoad($(this).attr('href'));
});
$(document).on('submit', 'form#frm', function (event) {
    event.preventDefault();
    var form = $(this);
    var data = new FormData($(this)[0]);
    var url = form.attr("action");
    $.ajax({
        type: form.attr('method'),
        url: url,
        data: data,
        cache: false,
        contentType: false,
        processData: false,
        success: function (data) {
            $('.is-invalid').removeClass('is-invalid');
            if (data.fail) {
                for (control in data.errors) {
                    $('#' + control).addClass('is-invalid');
                    $('#error-' + control).html(data.errors[control]);
                }
            } else {
                ajaxLoad(data.redirect_url);
            }
        },
        error: function (xhr, textStatus, errorThrown) {
            alert("Error: " + errorThrown);
        }
    });
    return false;
});
function ajaxLoad(filename, content) {
    content = typeof content !== 'undefined' ? content : 'content';
    $('.loading').show();
    $.ajax({
        type: "GET",
        url: filename,
        contentType: false,
        success: function (data) {
            $("#" + content).html(data);
            $('.loading').hide();
        },
        error: function (xhr, status, error) {
            alert(xhr.responseText);
        }
    });
}
function ajaxDelete(filename, token, content) {
    content = typeof content !== 'undefined' ? content : 'content';
    $('.loading').show();
    $.ajax({
        type: 'POST',
        data: {_method: 'DELETE', _token: token},
        url: filename,
        success: function (data) {
            $("#" + content).html(data);
            $('.loading').hide();
        },
        error: function (xhr, status, error) {
            alert(xhr.responseText);
        }
    });
}

Step 6: Create View

Create layout view file default.blade.php in /demo/resources/views/layout. (create folder layout if it does not exist) 

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
@yield('head')
<!-- Styles -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
    @yield('css')
</head>
<body style="padding-top: 100px;padding-bottom: 50px;background: whitesmoke">
<nav class="navbar fixed-top navbar-expand-sm navbar-dark bg-info">
    <a class="navbar-brand" target="_blank" href="http://www.codovel.com">CODOVEL.COM</a>
    @yield('nav')
</nav>
@yield('content')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
@yield('js')
</body>
</html>

 

Create view file ajax.blade.php in /demo/resources/views/crud_3. (create folder crud_3 if it does not exist) 

@extends('layout.default')
@section('css')
    <style>
        .loading {
            background: lightgrey;
            padding: 15px;
            position: fixed;
            border-radius: 4px;
            left: 50%;
            top: 50%;
            text-align: center;
            margin: -40px 0 0 -50px;
            z-index: 2000;
            display: none;
        }

        a, a:hover {
            color: white;
        }

        .form-group.required label:after {
            content: " *";
            color: red;
            font-weight: bold;
        }
    </style>
@endsection
@section('content')
    <div id="content">
        @include('crud_3.index')
    </div>
    <div class="loading">
        <i class="fa fa-refresh fa-spin fa-2x fa-fw"></i><br/>
        <span>Loading</span>
    </div>
@endsection
@section('js')
    <script src="{{asset('js/ajax-crud.js')}}"></script>
    <script src="https://use.fontawesome.com/2c7a93b259.js"></script>
@endsection

 

Create view file index.blade.php in /demo/resources/views/crud_3. (create folder crud_3 if it does not exist)

<div class="container">
    <div class="float-right">
        <a href="javascript:ajaxLoad('{{url('laravel-crud-search-sort-ajax/create')}}')"
           class="btn btn-primary">New</a>
    </div>
    <h1 style="font-size: 2.2rem">Customers List (Laravel CRUD, Search, Sort - AJAX)</h1>
    <hr/>
    <div class="row">
        <div class="col-sm-4 form-group">
            {!! Form::select('gender',['-1'=>'Select Gender','Male'=>'Male','Female'=>'Female'],request()->session()->get('gender'),['class'=>'form-control','onChange'=>'ajaxLoad("'.url("laravel-crud-search-sort-ajax").'?gender="+this.value)']) !!}
        </div>
        <div class="col-sm-5 form-group">
            <div class="input-group">
                <input class="form-control" id="search"
                       value="{{ request()->session()->get('search') }}"
                       onkeydown="if (event.keyCode == 13) ajaxLoad('{{url('laravel-crud-search-sort-ajax')}}?search='+this.value)"
                       placeholder="Search name" name="search"
                       type="text" id="search"/>
                <div class="input-group-btn">
                    <button type="submit" class="btn btn-warning"
                            onclick="ajaxLoad('{{url('laravel-crud-search-sort-ajax')}}?search='+$('#search').val())"
                    >
                        Search
                    </button>
                </div>
            </div>
        </div>
    </div>
    <table class="table table-bordered bg-light">
        <thead class="bg-dark" style="color: white">
        <tr>
            <th width="60px" style="vertical-align: middle;text-align: center">No</th>
            <th style="vertical-align: middle">
                <a href="javascript:ajaxLoad('{{url('laravel-crud-search-sort-ajax?field=name&sort='.(request()->session()->get('sort')=='asc'?'desc':'asc'))}}')">
                    Name
                </a>
                {{request()->session()->get('field')=='name'?(request()->session()->get('sort')=='asc'?'&#9652;':'&#9662;'):''}}
            </th>
            <th style="vertical-align: middle">
                <a href="javascript:ajaxLoad('{{url('laravel-crud-search-sort-ajax?field=gender&sort='.(request()->session()->get('sort')=='asc'?'desc':'asc'))}}')">
                    Gender
                </a>
                {{request()->session()->get('field')=='gender'?(request()->session()->get('sort')=='asc'?'&#9652;':'&#9662;'):''}}
            </th>
            <th style="vertical-align: middle">
                <a href="javascript:ajaxLoad('{{url('laravel-crud-search-sort-ajax?field=email&sort='.(request()->session()->get('sort')=='asc'?'desc':'asc'))}}')">
                    Email
                </a>
                {{request()->session()->get('field')=='email'?(request()->session()->get('sort')=='asc'?'&#9652;':'&#9662;'):''}}
            </th>
            <th width="130px" style="vertical-align: middle">Action</th>
        </tr>
        </thead>
        <tbody>
        @php
            $i=1;
        @endphp
        @foreach($customers as $customer)
            <tr>
                <th style="vertical-align: middle;text-align: center">{{$i++}}</th>
                <td style="vertical-align: middle">{{ $customer->name }}</td>
                <td style="vertical-align: middle">{{ $customer->gender }}</td>
                <td style="vertical-align: middle">{{$customer->email}}</td>
                <td style="vertical-align: middle" align="center">
                    <a class="btn btn-primary btn-sm" title="Edit"
                       href="javascript:ajaxLoad('{{url('laravel-crud-search-sort-ajax/update/'.$customer->id)}}')">
                        Edit</a>
                    <input type="hidden" name="_method" value="delete"/>
                    <a class="btn btn-danger btn-sm" title="Delete"
                       href="javascript:if(confirm('Are you sure want to delete?')) ajaxDelete('{{url('laravel-crud-search-sort-ajax/delete/'.$customer->id)}}','{{csrf_token()}}')">
                        Delete
                    </a>
                </td>
            </tr>
        @endforeach
        </tbody>
    </table>
    <nav>
        <ul class="pagination justify-content-end">
            {{$customers->links('vendor.pagination.bootstrap-4')}}
        </ul>
    </nav>
</div>

Note: The above view I use boostrap 4 pagination. So please export laravel built-in pagination files by going to terminal or command prompt (for window users), navigate to your project directory (/demo), and run this command

php artisan vendor:publish --tag=laravel-pagination

The above command will place all pagination views in the /resources/views/vendor/pagination. You can customize and use the one you need.

Create view file form.blade.php in /demo/resources/views/crud_3. (create folder crud_3 if it does not exist)

<div class="container">
    <div class="col-md-8 offset-md-2">
        <h1>{{isset($customer)?'Edit':'New'}} Customer</h1>
        <hr/>
        @if(isset($customer))
            {!! Form::model($customer,['method'=>'put','id'=>'frm']) !!}
        @else
            {!! Form::open(['id'=>'frm']) !!}
        @endif
        <div class="form-group row required">
            {!! Form::label("name","Name",["class"=>"col-form-label col-md-3 col-lg-2"]) !!}
            <div class="col-md-8">
                {!! Form::text("name",null,["class"=>"form-control".($errors->has('name')?" is-invalid":""),"autofocus",'placeholder'=>'Name']) !!}
                <span id="error-name" class="invalid-feedback"></span>
            </div>
        </div>
        <div class="form-group row">
            {!! Form::label("gender","Gender",["class"=>"col-form-label col-md-3 col-lg-2"]) !!}
            <div class="col-md-8">
                {!! Form::select("gender",['Male'=>'Male','Female'=>'Female'],null,["class"=>"form-control"]) !!}
            </div>
        </div>
        <div class="form-group row required">
            {!! Form::label("email","Email",["class"=>"col-form-label col-md-3 col-lg-2"]) !!}
            <div class="col-md-8">
                {!! Form::text("email",null,["class"=>"form-control".($errors->has('email')?" is-invalid":""),'placeholder'=>'Email']) !!}
                <span id="error-email" class="invalid-feedback"></span>
            </div>
        </div>
        <div class="form-group row">
            <div class="col-md-3 col-lg-2"></div>
            <div class="col-md-4">
                <a href="javascript:ajaxLoad('{{url('laravel-crud-search-sort-ajax')}}')" class="btn btn-danger">
                    Back</a>
                {!! Form::button("Save",["type" => "submit","class"=>"btn
            btn-primary"])!!}
            </div>
        </div>
        {!! Form::close() !!}
    </div>
</div>

 

Step 6: Create Controller

Create controller file Crud3Controller in /demo/app/Http/Cotrollers.

<?php
namespace App\Http\Controllers;

use App\Customer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class Crud3Controller extends Controller
{
    public function index(Request $request)
    {
        $request->session()->put('search', $request->has('search') ? $request->get('search') : ($request->session()->has('search') ? $request->session()->get('search') : ''));
        $request->session()->put('gender', $request->has('gender') ? $request->get('gender') : ($request->session()->has('gender') ? $request->session()->get('gender') : -1));
        $request->session()->put('field', $request->has('field') ? $request->get('field') : ($request->session()->has('field') ? $request->session()->get('field') : 'name'));
        $request->session()->put('sort', $request->has('sort') ? $request->get('sort') : ($request->session()->has('sort') ? $request->session()->get('sort') : 'asc'));
        $customers = new Customer();
        if ($request->session()->get('gender') != -1)
            $customers = $customers->where('gender', $request->session()->get('gender'));
        $customers = $customers->where('name', 'like', '%' . $request->session()->get('search') . '%')
            ->orderBy($request->session()->get('field'), $request->session()->get('sort'))
            ->paginate(5);
        if ($request->ajax())
            return view('crud_3.index', compact('customers'));
        else
            return view('crud_3.ajax', compact('customers'));
    }

    public function create(Request $request)
    {
        if ($request->isMethod('get'))
            return view('crud_3.form');
        else {
            $rules = [
                'name' => 'required',
                'email' => 'required|email',
            ];
            $validator = Validator::make($request->all(), $rules);
            if ($validator->fails())
                return response()->json([
                    'fail' => true,
                    'errors' => $validator->errors()
                ]);
            $customer = new Customer();
            $customer->name = $request->name;
            $customer->gender = $request->gender;
            $customer->email = $request->email;
            $customer->save();
            return response()->json([
                'fail' => false,
                'redirect_url' => url('laravel-crud-search-sort-ajax')
            ]);
        }
    }

    public function delete($id)
    {
        Customer::destroy($id);
        return redirect('/laravel-crud-search-sort');
    }

    public function update(Request $request, $id)
    {
        if ($request->isMethod('get'))
            return view('crud_3.form', ['customer' => Customer::find($id)]);
        else {
            $rules = [
                'name' => 'required',
                'email' => 'required|email',
            ];
            $validator = Validator::make($request->all(), $rules);
            if ($validator->fails())
                return response()->json([
                    'fail' => true,
                    'errors' => $validator->errors()
                ]);
            $customer = Customer::find($id);
            $customer->name = $request->name;
            $customer->gender = $request->gender;
            $customer->email = $request->email;
            $customer->save();
            return response()->json([
                'fail' => false,
                'redirect_url' => url('laravel-crud-search-sort-ajax')
            ]);
        }
    }
}

 

Step 7: Test

Open your browser and type http://localhost/demo/public/laravel-crud-search-sort-ajax. Then you will see it.

laravel 5.5 ajax CRUD search sort pagination

Hope you can do it.


Demo


Related Posts

© 2018 All Rights Reserved.