In this tutorial, we are going to learn how to implement Datatble in Laravel. When we need to visulaize large number of Data with the actions like Edit,Delete Datatable is the easiet way. This Datatable feature provide facilities like:

  • Pagination
  • Multi Column Ordering
  • Instant Search and etc.
  • Prerequisites

  • Laravel
  • To Continue with this tutorial, you should have installed Laravel 8 in your pc. If you are still not installed Laravel in your machine you can configure it from here.

    Setting up the Project

    First you need to create a new laravel project by running below command in your terminal
    1
    composer create-project laravel/laravel laravel-datatable

    Then navigate to your project directory by using below command in your terminal

    1
    cd laravel-datatable

    Setting up Database

    To setup up Database for our project, open the application using your favourite text editor and and then navigate to .env file in it and then change below section acording to your Database settings:

    1
    2
    3
    4
    5
    6
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel-datatable
    DB_USERNAME=root
    DB_PASSWORD=

    Install Yajra Datatable

    Now we need to install Yajra Datatable composer package for our application. It is a jquery Databale api which handle server side works using Ajax options. To install Yajra Datatable run below command in your terminal:

    1
    composer require yajra/laravel-datatables-oracle

    After that, we need to configure it in our config/app.php file.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    'providers' => [

    ....
    ....
    App\Providers\RouteServiceProvider::class,
    Yajra\DataTables\DataTablesServiceProvider::class,

    ],
    'aliases' => [

    ....
    ....
    'DataTables' => Yajra\DataTables\Facades\DataTables::class,
    ],
    ];

    Then run:

    1
    php artisan vendor:publish --provider="Yajra\DataTables\DataTablesServiceProvider

    Note:This step is optional.

    Create Model & Run Migration

    To make the connection between the client and the server, we we require to create the User model by running below command:
    1
    php artisan make:model User 

    After executing the above command, navigate to database/migrations/timestamp_create_users_table and change it shown as below:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <?php

    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;

    class CreateUsersTable extends Migration
    {
    public function up()
    {
    Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
    $table->string('phone');
    $table->string('address');
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
    });
    }

    public function down()
    {
    Schema::dropIfExists('posts');
    }
    }

    Then navigate to app/Models/User.php file and register the following values inside $fillablearray.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?php

    namespace App\Models;

    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;

    class Post extends Model
    {
    use HasFactory;
    protected $fillable = [
    'name',
    'email',
    'password',
    'phone',
    'address'
    ];
    }

    Then, run the migration by using the below command:

    1
    php artisan migrate

    Create User Controller

    Now we need to create contoller to handle our core logic for handling our Datatable and views. To create new controller:
    1
    php artisan make:controller UserController

    After that open your app/Http/Controllers/UserController.php and paste below code in it:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    public function index()
    {
    return view('admin.user-management.user.index');
    }

    /* Get all users */
    public function getAllUsers()
    {
    $users = DB::table('users')->get();
    return DataTables::of($users)->make();
    }

    public function create()
    {
    return view('admin.user-management.user.create');
    }

    public function store(Request $request)
    {
    $request->validate([
    'name' => ['required', 'string', 'max:255'],
    'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
    'password' => ['required', 'string', 'min:8'],
    'phone'=> ['required','string'],
    'address'=> ['required', 'string'],
    ]);

    User::create([
    'name' => $request->name,
    'email' => $request->email,
    'password' => Hash::make($request->password),
    'address' => $request->address,
    'phone' => $request->phone,
    ]);

    return redirect()->back();
    }

    public function show($id)
    {
    //
    }

    public function edit($id)
    {
    $user = User::findOrFail($id);
    return view('admin.user-management.user.edit', [
    'user' => $user,
    ]);
    }

    public function update(Request $request, $id)
    {

    $request->validate([
    'name' => 'string', 'max:255',
    'email' => 'string', 'email', 'max:255', 'unique:users',
    'password' => 'string', 'min:8',
    'phone'=> 'string',
    'address'=> 'string',
    ]);

    $data = [
    'name' => $request->name,
    'email' => $request->email,
    'phone' => $request->phone,
    'address' => $request->address,
    ];

    User::findOrFail($id)->update($data);
    return redirect()->back();
    }

    public function destroy($id)
    {
    $user = User::findOrFail($id);
    $user->delete();

    return redirect()->back();
    }

    Create Views

    Inside resources -> views folder create, folder called layouts. Then create an app.blade.php file inside i and add the following code.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    <!DOCTYPE html>
    <html lang="en">

    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Meta -->
    <meta name="description" content="">
    <meta name="author" content="">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    @if (isset($title))
    <title>{{ $title }}</title>
    @else
    <title>Laravel Datatable</title>
    @endif

    <link href="{{ asset('assets/lib/font-awesome/css/font-awesome.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/lib/Ionicons/css/ionicons.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/lib/perfect-scrollbar/css/perfect-scrollbar.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/lib/jquery-switchbutton/jquery.switchButton.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/lib/rickshaw/rickshaw.min.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/lib/chartist/chartist.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/lib/highlightjs/github.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/lib/datatables/jquery.dataTables.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/lib/select2/css/select2.min.css') }}" rel="stylesheet">
    <link href="{{ asset('assets/css/zoom.css') }}" rel="stylesheet">

    <link rel="stylesheet" href="{{ asset('assets/css/bracket.css') }}">

    @yield('css')

    </head>

    <body>

    @include('layouts.inc.left_nav')

    @include('layouts.inc.top_navbar')


    <div class="br-mainpanel">

    @yield('content')

    </div>


    <script src="{{ asset('assets/lib/jquery/jquery.js') }}"></script>
    <script src="{{ asset('assets/lib/popper.js/popper.js') }}"></script>
    <script src="{{ asset('assets/lib/bootstrap/bootstrap.js') }}"></script>
    <script src="{{ asset('assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.js') }}"></script>
    <script src="{{ asset('assets/lib/moment/moment.js') }}"></script>
    <script src="{{ asset('assets/lib/jquery-ui/jquery-ui.js') }}"></script>
    <script src="{{ asset('assets/lib/jquery-switchbutton/jquery.switchButton.js') }}"></script>
    <script src="{{ asset('assets/lib/peity/jquery.peity.js') }}"></script>
    <script src="{{ asset('assets/lib/chartist/chartist.js') }}"></script>
    <script src="{{ asset('assets/lib/jquery.sparkline.bower/jquery.sparkline.min.js') }}"></script>
    <script src="{{ asset('assets/lib/d3/d3.js') }}"></script>
    <script src="{{ asset('assets/lib/rickshaw/rickshaw.min.js') }}"></script>

    <script src="{{ asset('assets/lib/highlightjs/highlight.pack.js') }}"></script>
    <script src="{{ asset('assets/lib/datatables/jquery.dataTables.js') }}"></script>
    <script src="{{ asset('assets/lib/datatables-responsive/dataTables.responsive.js') }}"></script>
    <script src="{{ asset('assets/lib/select2/js/select2.min.js') }}"></script>


    <script src="{{ asset('assets/js/bracket.js') }}"></script>
    <script src="{{ asset('assets/js/ResizeSensor.js') }}"></script>
    <script src="{{ asset('assets/js/dashboard.js') }}"></script>

    @yield('js')

    <script>
    $(function() {
    'use strict'
    $(window).resize(function() {
    minimizeMenu();
    });

    minimizeMenu();

    function minimizeMenu() {
    if (window.matchMedia('(min-width: 992px)').matches && window.matchMedia('(max-width: 1299px)')
    .matches) {
    // show only the icons and hide left menu label by default
    $('.menu-item-label,.menu-item-arrow').addClass('op-lg-0-force d-lg-none');
    $('body').addClass('collapsed-menu');
    $('.show-sub + .br-menu-sub').slideUp();
    } else if (window.matchMedia('(min-width: 1300px)').matches && !$('body').hasClass(
    'collapsed-menu')) {
    $('.menu-item-label,.menu-item-arrow').removeClass('op-lg-0-force d-lg-none');
    $('body').removeClass('collapsed-menu');
    $('.show-sub + .br-menu-sub').slideDown();
    }
    }
    });

    </script>
    </body>
    </html>

    Note: Here I have used a premium and licensed template to get a better and interactive output from our application. If you need to use this template you need to purchase it from it's respective owners.

    Next, you need to create a folder called inc in layouts directory and create two seperate file called left_nav.blade.php and top_navbar.blade.php and paste below codes:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!-- left_nav.blade.php -->

    <div class="br-logo"><a href=""><span>[</span>CodingtrickS<span>]</span></a></div>
    <div class="br-sideleft overflow-y-auto">
    <label class="sidebar-label pd-x-15 mg-t-20">Navigation</label>
    <div class="br-sideleft-menu">
    <a href="" class="br-menu-link">
    <div class="br-menu-item">
    <i class="menu-item-icon icon ion-ios-filing-outline tx-24"></i>
    <span class="menu-item-label">User Management</span>
    <i class="menu-item-arrow fa fa-angle-down"></i>
    </div>
    </a>
    <ul class="br-menu-sub nav flex-column">
    <li @if (\Request::is('user')) class='active' @endif class="nav-item"><a href="{{ route('user.index') }}" class="nav-link">All Users</a></li>
    <li @if (\Request::is('user/create')) class='active' @endif class="nav-item"><a href="{{ route('user.create') }}" class="nav-link">Create User</a></li>
    </ul>
    </div>
    </div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <!-- top_nav.blade.php -->

    <div class="br-header">
    <div class="br-header-left">
    <div class="navicon-left hidden-md-down"><a id="btnLeftMenu" href=""><i class="icon ion-navicon-round"></i></a></div>
    <div class="navicon-left hidden-lg-up"><a id="btnLeftMenuMobile" href=""><i class="icon ion-navicon-round"></i></a></div>
    <div class="input-group hidden-xs-down wd-170 transition">
    <input id="searchbox" type="text" class="form-control" placeholder="Search">
    <span class="input-group-btn">
    <button class="btn btn-secondary" type="button"><i class="fa fa-search"></i></button>
    </span>
    </div>
    </div>
    <div class="br-header-right">
    <nav class="nav">
    </nav>
    <div class="navicon-right">
    <a id="btnRightMenu" href="" class="pos-relative">
    <i class="icon ion-ios-chatboxes-outline"></i>
    <span class="square-8 bg-danger pos-absolute t-10 r--5 rounded-circle"></span>
    </a>
    </div>
    </div>
    </div>

    Inside resources -> views folder create, folder called admin. Then create folder called user-management and create folder called user in it. Then create three separate files called create.blade.php,edit.blade.php and index.blade.php inside it and add the following code.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    <!--create.blade.php -->

    @extends('layouts.app')

    @section('content')

    <div class="br-pageheader pd-y-15 pd-l-20">
    <nav class="breadcrumb pd-0 mg-0 tx-12">

    </nav>
    </div>
    <div class="br-pagebody">
    <div class="br-section-wrapper">
    <form method="POST" enctype="multipart/form-data" action="{{ route('user.store') }}">
    @csrf
    <div class="form-layout form-layout-1">
    <div class="row mg-b-25">
    <div class="col-lg-4">
    <div class="form-group">
    <label class="form-control-label">Name: <span class="tx-danger">*</span></label>
    <input class="form-control" type="text" id="name" class="form-control @error('name') is-invalid @enderror" name="name" required >
    @error('name')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    <div class="col-lg-4">
    <div class="form-group">
    <label class="form-control-label">Phone <span class="tx-danger">*</span></label>
    <input class="form-control" type="text" id="phone" class="form-control @error('phone') is-invalid @enderror" name="phone" required >
    @error('phone')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    <div class="col-lg-4">
    <div class="form-group">
    <label class="form-control-label">Email address: <span class="tx-danger">*</span></label>
    <input class="form-control" type="email" id="email" class="form-control @error('email') is-invalid @enderror" name="email" required >
    @error('email')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    <div class="col-lg-8">
    <div class="form-group mg-b-10-force">
    <label class="form-control-label">Address: <span class="tx-danger">*</span></label>
    <input class="form-control" type="text" name="address" value="" class="form-control @error('address') is-invalid @enderror required placeholder="Enter Address">
    @error('address')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    <div class="col">
    <div class="form-group mg-b-10-force">
    <label class="form-control-label">Password <span class="tx-danger">*</span></label>
    <input class="form-control" type="password" id="password" class="form-control @error('password') is-invalid @enderror" name="password" required >
    @error('password')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    </div>
    <div class="form-layout-footer">
    <button type="submit" class="btn btn-info">Create new user</button>
    <button class="btn btn-secondary">Cancel</button>
    </div>
    </form>
    </div>
    </div>
    </div>

    @endsection
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    <!--edit.blade.php -->

    @extends('layouts.app')

    @section('content')

    <div class="br-pageheader pd-y-15 pd-l-20">
    <nav class="breadcrumb pd-0 mg-0 tx-12">

    </nav>
    </div>
    <div class="br-pagebody">
    <div class="br-section-wrapper">
    <form method="POST" enctype="multipart/form-data" action="{{ route('user.update', ['user' => $user->id]) }}">
    @csrf
    @method('PUT')
    <div class="form-layout form-layout-1">
    <div class="row mg-b-25">
    <div class="col-lg-4">
    <div class="form-group">
    <label class="form-control-label">Name: <span class="tx-danger">*</span></label>
    <input class="form-control" type="text" name="name" value="{{ $user->name }}" placeholder="Enter Name">
    @error('name')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    <div class="col-lg-4">
    <div class="form-group">
    <label class="form-control-label">Phone: <span class="tx-danger">*</span></label>
    <input class="form-control" type="text" name="phone" value="{{ $user->phone }}" placeholder="Enter phone Number">
    @error('phone')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    <div class="col-lg-4">
    <div class="form-group">
    <label class="form-control-label">Email address: <span class="tx-danger">*</span></label>
    <input class="form-control" type="text" name="email" value="{{ $user->email}}" placeholder="Enter Email Address">
    @error('email')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    <div class="col-lg-8">
    <div class="form-group mg-b-10-force">
    <label class="form-control-label">Address: <span class="tx-danger">*</span></label>
    <input class="form-control" type="text" name="address" value="{{ $user->address}}" placeholder="Enter Address">
    @error('address')
    <span class="invalid-feedback" role="alert">
    <strong>{{ $message }}</strong>
    </span>
    @enderror
    </div>
    </div>
    </div>
    <div class="form-layout-footer">
    <button type="submit" class="btn btn-info">Update</button>
    <button type="reset" class="btn btn-secondary">Cancel</button>
    </div>
    </div>
    </form>
    </div>
    </div>
    @endsection
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    <!--index.blade.php -->

    @extends('layouts.app')

    @section('content')

    <div class="br-pageheader pd-y-15 pd-l-20">
    <nav class="breadcrumb pd-0 mg-0 tx-12">
    </nav>
    </div>
    <div class="pd-x-20 pd-sm-x-30 pd-t-20 pd-sm-t-30">
    <h4 class="tx-gray-800 mg-b-5">Data Table</h4>
    <p class="mg-b-0">DataTables is a plug-in for the jQuery Javascript library.</p>
    </div>
    <div class="br-pagebody">
    <div class="br-section-wrapper">
    <div class="table-wrapper">
    <table id="users" class="table display responsive nowrap" style=" overflow-x:auto;">
    <thead>
    <tr>
    <th class="wd-20p">Name</th>
    <th class="wd-20p">Address</th>
    <th class="wd-20p">Email</th>
    <th class="wd-20p">Phone</th>
    <th class="wd-20p">Action</th>
    </tr>
    </thead>
    </table>
    </div>
    </div>
    </div>

    @endsection

    @section('js')

    <script src="//code.jquery.com/jquery-1.12.3.js"></script>
    <script src="//cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>

    <script>
    $(function () {
    var table = $('#users').DataTable({
    "processing": true,
    "serverSide": true,
    "pageLength": 10,
    "responsive": true,
    "searching": true,
    "bAutoWidth": false,
    scrollY: true,
    scrollX: true,
    scrollCollapse: true,
    "ajax": {
    url: "{{ config('app.url') }}/user/get/all",
    type: "GET",
    cache: false,
    error: function () {
    $("#users").append(
    '<tbody class="errors"><tr><th colspan="7">No Data to show</th></tr></tbody>'
    );
    }
    },
    "columns": [
    {data: 'name'},
    {data: 'address'},
    {data: 'email'},
    {data: 'phone'},
    {data: 'id'},
    ],
    fnRowCallback: function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {

    $('td:eq(0)', nRow).html(aData['name']);
    $('td:eq(1)', nRow).html(aData['address']);
    $('td:eq(2)', nRow).html(aData['email']);
    $('td:eq(3)', nRow).html(aData['phone']);

    var actions = '<a href="{{ route("user.index") }}/' + aData['id'] +'/edit" class="btn btn-xs btn-warning mr-2"><i class="fa fa-pencil"></i></a>';
    actions += `<form action="{{ route("user.index") }}/` + aData['id'] +`" method="post" onsubmit="return confirm('Are you sure you want to delete?');" style='display: -webkit-inline-box;'>`;
    actions += '@csrf @method("Delete")';
    actions +='<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash-o"></i></button>';
    actions += '</a>';
    $('td:eq(4)', nRow).html(actions);
    }
    });
    });

    </script>
    @endsection

    Now we have already finished with our all required views. You can find all the assets files it need for this application from my Github repo.

    Define Routes

    Navigate to routes/web.php file and paste below code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php

    use Illuminate\Support\Facades\Route;
    use App\Http\Controllers\UserController;

    Route::get('/',function () {
    return view('admin.user-management.user.index');
    });
    Route::get('user/get/all', [UserController::class, 'getAllUsers']);
    Route::resource('/user', UserController::class);

    Run our application

    Now we have already finished our application. Now we can run your application using below command:

    1
    php artisan serve

    Now, navigate to http://localhost:8000 in your browser.

    Conclusion

    In this tutorial, we implemented Datatable in Laravel. If you have any issue regarding this tutorial, mention your issue in comment section or reach me through my E-mail. You can obtain complete source code and asset files for this tutorial from this GitHub repository.