Hello all, Now i will show you how we can use datatable in Laravel 9 project.
Most important is i will use Deferred loading data. You can read about its from the URL https://datatables.net/examples/server_side/defer_loading.html.
Step 1. Install Laravel 9.
Step 2. Connect with your database.
Step 3. Insert some data in your table. You can use seeder or anything which you want to insert data in table.
Step 4. Connect Datatable with CDN and configure the Blade file.
https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css
https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js
widget_list.blade.php
<x-admin_header></x-admin_header> <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap2-toggle.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="{{$_ENV['APP_URL']}}assets/date-picker/DateTimePicker.css" /> <!-- Main Content --> <div id="content"> <!-- Topbar --> <nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow"> <!-- Sidebar Toggle (Topbar) --> <button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3"> <i class="fa fa-bars"></i> </button> <!-- Topbar Search --> <!-- Topbar Navbar --> <ul class="navbar-nav ml-auto"> <!-- Nav Item - Search Dropdown (Visible Only XS) --> <li class="nav-item dropdown no-arrow d-sm-none"> <a class="nav-link dropdown-toggle" href="#" id="searchDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i class="fas fa-search fa-fw"></i> </a> <!-- Dropdown - Messages --> <div class="dropdown-menu dropdown-menu-right p-3 shadow animated--grow-in" aria-labelledby="searchDropdown"> <form class="form-inline mr-auto w-100 navbar-search"> <div class="input-group"> <input type="text" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2"> <div class="input-group-append"> <button class="btn btn-primary" type="button"> <i class="fas fa-search fa-sm"></i> </button> </div> </div> </form> </div> </li> <div class="topbar-divider d-none d-sm-block"></div> <!-- Nav Item - User Information --> <li class="nav-item dropdown no-arrow"> <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <span class="mr-2 d-none d-lg-inline text-gray-600 small">{{auth()->user()->name}}</span> <img class="img-profile rounded-circle" src="{{auth()->user()->profile_photo_url}})"> </a> <!-- Dropdown - User Information --> <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown"> <a class="dropdown-item" href="#"> <i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i> Profile </a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#" data-toggle="modal" data-target="#logoutModal"> <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i> Logout </a> </div> </li> </ul> </nav> <!-- End of Topbar --> <!-- Begin Page Content --> <div class="container-fluid"> <!-- Page Heading --> <div class="d-sm-flex align-items-center justify-content-between mb-4"> <div class="col-sm-6"> <h1 class="h3 mb-4 text-gray-800">Widgets</h1> </div> <div class="col-sm-6"> <a href='/admin-new-widget' style="float: right" class=" mb-4 button button-successd-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"> <i class="fas fa-plus fa-sm text-white-50"></i> Add Widget<a> </div> </div> <div class="row"> <!-- Area Chart --> <div class="col-xl-12 col-lg-12"> <div class="card shadow mb-4"> <!-- Card Header - Dropdown --> <!-- Card Body --> <div class="card-body"> @if (session('success')) <div class="alert alert-success"> <p class="msg"> {{ session('success') }}</p> </div> @endif <div class="row"> <div class="col-sm-12"> <div class="table-responsive"> <table class="table table-bordered text-center" id="campaign_list_dataTable" width="100%" cellspacing="0"> <thead> <tr> <th style="width: 6%">Id</th> <th>Pub Name</th> <th>Title</th> <th>Domain</th> <th>Category</th> <th>Language</th> <th>Created Date</th> <th>Status</th> <th>Action</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> </div> </div> </div> </div> </div> </div> <!-- /.container-fluid --> <!-- Modal --> <div class="modal model-lg fade" id="myModal" role="dialog"> <div class="modal-dialog" style="max-width:800px !important;"> <!-- Modal content--> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">widget Code</h4> <button type="button" class="close" data-dismiss="modal">×</button> </div> <div class="modal-body"> </div> <div class="modal-footer"> <button type="button" id="copy_button" class="btn btn-warning" onclick="copyToClipboard();">Copy Code</button> </div> </div> </div> </div> {{-- END MODEL --}} </div> <!-- End of Main Content --> <x-admin_footer></x-admin_footer> <script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap2-toggle.min.js"></script> <link href="https://cdn.datatables.net/1.10.23/css/jquery.dataTables.min.css" rel="stylesheet"/> <script src="{{$_ENV['APP_URL']}}assets/cdn/jquery.dataTables.min.js"></script> <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script> <script> $(document).ready(function() { filter_list(); $('.alert-success').fadeIn().delay(10000).fadeOut(); }); </script> <script> function filter_list(){ var conditionv2 = "widgets_id!=''"; // var date_filter = $("#date_filter").val(); var date_filter=""; // DATE FILTER if (date_filter.length > 0) { var myarr = date_filter.split("To"); if (conditionv2.length > 0) { var date1 = myarr[0]; var date2 = myarr[1]; conditionv2 = conditionv2 + " AND DATE(ads_time) >='" + date1 + "' AND DATE(ads_time) <= '"+date2+"'"; } else { var date1 = myarr[0]; var milliseconds1 = date1.getTime(); var date2 = myarr[1]; var milliseconds2 = date2.getTime(); conditionv2 = "DATE(ads_time) >='" + date1 + "' AND DATE(ads_time) <= '" + date2 + "'"; } // alert(conditionv2); } var _token = $("input[name='_token']").val(); var table = $('#campaign_list_dataTable').DataTable(); table.destroy(); var url = "/admin-datalist-widgets"; console.log(url); var table = $('#campaign_list_dataTable').DataTable({ "processing": true, //Feature control the processing indicator. "serverSide": true, //Feature control DataTables' server-side processing mode. "bAutoWidth": false, "order": [], //Initial no order. "stateSave": false, // Load data for the table's content from an Ajax source "ajax": { "url": url, "type": "post", "data": function (data) { data.condition = conditionv2; }, headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }, //Set column definition initialisation properties. "columnDefs": [ { "targets": [], //first column / numbering column "orderable": false, //set not orderable }, ], "lengthMenu": [[10, 500, 1000, 2000], [10, 500, 1000, 2000]], }); } </script> <script> function change_status(id){ swal({ title: "Are you sure?", icon: "warning", buttons: true, dangerMode: true, }) .then((willDelete) => { if (willDelete) { $.ajax({ type: "GET", dataType: 'json', url: "{{$_ENV['APP_URL']}}admin-widget-activate/"+id, data: {"id":id}, //send the selected area value success: function (data) { location.reload(); } }); } else { swal("You cancelled the action."); } }); } </script> <script> function open_model(id){ // alert(id); $(".modal-body").empty(); $(".modal-body").append('<p><div id="widget_code" style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><div id=<span style="color: #0000FF">"TopSlots'+id+'"</span>> <br><script type=<span style="color: #0000FF">"text/javascript"</span> data-cfasyn=<span style="color: #0000FF">"false"</span> async=<span style="color: #0000FF">"true"</span> src=<span style="color: #0000FF">"{{$_ENV['API_URL']}}api/videoads/'+id+'"</span>><<span style="color: #a61717; background-color: #e3d2d2">/script><br></div></span></pre></div></p>'); $("#myModal").modal('show'); // $('#exampleModal').modal('show'); } </script> <script> function copyToClipboard() { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(document.getElementById('widget_code')); range.select().createTextRange(); document.execCommand("copy"); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(document.getElementById('widget_code')); window.getSelection().addRange(range); document.execCommand("copy"); // alert("Text has been copied, now paste in the text-area") // $("#copy_button").setText("Copied"); $("#copy_button").html('Copied'); } } </script>
Step 5. Create controller and Model.
<script> $(document).ready(function() { filter_list(); }); </script> <script> function filter_list(){ var conditionv2 = "widgets_id!=''"; // var date_filter = $("#date_filter").val(); var date_filter=""; // DATE FILTER if (date_filter.length > 0) { var myarr = date_filter.split("To"); if (conditionv2.length > 0) { var date1 = myarr[0]; var date2 = myarr[1]; conditionv2 = conditionv2 + " AND DATE(ads_time) >='" + date1 + "' AND DATE(ads_time) <= '"+date2+"'"; } else { var date1 = myarr[0]; var milliseconds1 = date1.getTime(); var date2 = myarr[1]; var milliseconds2 = date2.getTime(); conditionv2 = "DATE(ads_time) >='" + date1 + "' AND DATE(ads_time) <= '" + date2 + "'"; } // alert(conditionv2); } var _token = $("input[name='_token']").val(); var table = $('#campaign_list_dataTable').DataTable(); table.destroy(); var url = "/admin-datalist-widgets"; console.log(url); var table = $('#campaign_list_dataTable').DataTable({ "processing": true, //Feature control the processing indicator. "serverSide": true, //Feature control DataTables' server-side processing mode. "bAutoWidth": false, "order": [], //Initial no order. "stateSave": false, // Load data for the table's content from an Ajax source "ajax": { "url": url, "type": "post", "data": function (data) { data.condition = conditionv2; }, headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }, //Set column definition initialisation properties. "columnDefs": [ { "targets": [], //first column / numbering column "orderable": false, //set not orderable }, ], "lengthMenu": [[10, 500, 1000, 2000], [10, 500, 1000, 2000]], }); } </script>
filter_list is the datatable method which will call on document ready. admin-datalist-widgets is a route.
web.php
Route::post("/admin-datalist-widgets",[AdmWidgetController::class,"get_data_table_list"]);
AdmWidgetController.php
public function get_data_table_list(Request $req){ $post=$req->input(); if($req->has("search")){ $condition = $req->search; $list=AdmWidgetsModel::leftJoin('languages', 'languages.language_id', '=', 'widgets_language') ->join('users', 'users.id', '=', 'widgets_user_id') ->join('site', 'site.site_id', '=', 'widgets_site_id') ->whereRaw($req->condition) ->where(function($query) use ($condition) { // Below line is for Whatever you type in Search box in datatable $query->orWhere('widgets_id', 'like', '%' . $condition['value'] . '%') ->orWhere('widgets_id', 'like', '%' . $condition['value'] . '%') ->orWhere('widgets_title', 'like', '%' . $condition['value'] . '%') ->orWhere('site_domian', 'like', '%' . $condition['value'] . '%') ->orWhere('name', 'like', '%' . $condition['value'] . '%'); }) ->orderByRaw('widgets_id DESC') ->offset($req->start) ->limit($req->length) ->get(); }else{ } $data = array(); if($req->has("start")){ $no =$req->start; }else{ $no =0; } foreach ($list as $v_list) { $no++; $row = array(); $row[] = $v_list->widgets_id; $row[] = $v_list->name."<br>".'<a class="mailto" href="mailto:'.$v_list->email.'"><small>'.$v_list->email.'</small></a>'; $row[] = $v_list->widgets_title; $row[] = "<a href='http://$v_list->site_domian' target='_blank'>".$v_list->site_domian."</a>"; if(!empty($v_list->widgets_category)){ $category=DB::select(DB::raw("SELECT GROUP_CONCAT(site_category_name) as category FROM `site_category` WHERE site_category_id IN($v_list->widgets_category)")); $row[] = $category[0]->category; }else{ $row[]=""; } $row[] = $v_list->language_name; $row[] = '<small>'.$v_list->widgets_created_date.'</small>'; if($v_list->widgets_status=="0"){ $row[] = '<label class="badge badge-danger">Off</label>'; $row[]='<label class="switch"><input type="checkbox" onchange="change_status('.$v_list->widgets_id.');"><span class="slider round"></span></label> <a href="/admin-widgets-view/'.$v_list->widgets_id.'" class="btn btn-warning btn-circle btn-sm" title="Edit"><i class="fas fa-pen"></i></a> <a onclick="open_model('.$v_list->widgets_id.');" href="javascript:void(0)" class="btn btn-info btn-circle btn-sm" title="Widget Code"><i class="fas fa-code"></i></a>'; // $row[] = '<a href="/admin-widget-activate/'.$v_list->widgets_id.'" class="btn btn-success btn-circle btn-sm" title="Activate"><i class="fas fa-check"></i></a>'.' '; }else if($v_list->widgets_status=="2"){ $row[] = '<label class="badge badge-success">On</label>'; $row[]='<label class="switch"><input type="checkbox" checked onchange="change_status('.$v_list->widgets_id.');"><span class="slider round"></span></label> <a href="/admin-widgets-view/'.$v_list->widgets_id.'" class="btn btn-warning btn-circle btn-sm" title="Edit"><i class="fas fa-pen"></i></a> <a onclick="open_model('.$v_list->widgets_id.');" href="javascript:void(0)" class="btn btn-info btn-circle btn-sm" title="Widget Code"><i class="fas fa-code"></i></a>'; // $row[] = '<a href="/admin-widget-block/'.$v_list->widgets_id.'" class="btn btn-danger btn-circle btn-sm" title="Block"><i class="fas fa-minus"></i></a>'.' '; }else if($v_list->widgets_status=="3"){ $row[] = '<label class="badge badge-danger">Off</label>'; $row[]='<label class="switch"><input type="checkbox" onchange="change_status('.$v_list->widgets_id.');"><span class="slider round"></span></label> <a href="/admin-widgets-view/'.$v_list->widgets_id.'" class="btn btn-warning btn-circle btn-sm" title="Edit"><i class="fas fa-pen"></i></a> <a onclick="open_model('.$v_list->widgets_id.');" href="javascript:void(0)" class="btn btn-info btn-circle btn-sm" title="Widget Code"><i class="fas fa-code"></i></a>'; } $data[] = $row; } if($req->has("search")){ $condition = $req->search; $output = array( "draw" => $req->draw, "recordsTotal" => AdmWidgetsModel::count(), "recordsFiltered" => AdmWidgetsModel::leftJoin('languages', 'languages.language_id', '=', 'widgets_language') ->join('users', 'users.id', '=', 'widgets_user_id') ->join('site', 'site.site_id', '=', 'widgets_site_id') ->whereRaw($req->condition) ->where(function($query) use ($condition) { $query->orWhere('widgets_id', 'like', '%' . $condition['value'] . '%') ->orWhere('widgets_id', 'like', '%' . $condition['value'] . '%') ->orWhere('widgets_id', 'like', '%' . $condition['value'] . '%') ->orWhere('widgets_id', 'like', '%' . $condition['value'] . '%'); })->count(), "data" => $data, ); }else{ $output = array( "draw" => $req->draw, "recordsTotal" => AdmWidgetsModel::count(), "recordsFiltered" => AdmWidgetsModel::count(), "data" => $data, ); } //output to json format echo json_encode($output); }
AdmWidgetsModel.php
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class AdmWidgetsModel extends Model { protected $table = 'widgets'; protected $primaryKey = 'widgets_id'; public $timestamps = false; use HasFactory; }
Step 6. Final check the result.
Now this integration is done, you can check your project .
Advantage of using datatable is
- Less Coding.
- No load on server with high data volume.
- Well design table.
- Export buttons inbuilt (Excel, PDF, CSV etc)
Thanks for Reading
Happy Coding.