Hiển thị và phân trang,tìm kiếm trong Laravel và Datatables

Mình xin giới thiệu với các bạn hướng dẫn dùng laravel với DataTables
DataTables là gì?
DataTables là một jQuery plugin support việc tạo bảng danh sách và thêm các tương tác vào đó. DataTables cung cấp tính năng tìm kiếm, sắp xếp và phân trang mà không cần thiết lập thêm gì.
Bước 1: Tạo project laravel
Ở đây mình dùng laravel 5.4.Tạo project blog bằng lệnh sau:

composer create-project --prefer-dist laravel/laravel blog

Bước 2 : Tạo database
Sử dụng Laravel Migration để tạo bảng news

D:\xampp\htdocs\blog>php artisan make:migration create_news_table --create=news

Created Migration: 2018_09_08_040811_create_news_table
Thêm code tạo bảng news vào file 2018_09_08_040811_create_news_table

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
class CreateNewsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
       
        Schema::create('news', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title')->unique();
            $table->timestamps();
        });
        $arrayData = [
            [
                'title'      => 'Lạnh người với loạt Screenshots vừa được Resident Evil 2 Remake nhá hàng',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'Những kiến thức cần biết khi sử dụng Flare Gun trong PUBG Mobile',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'Đánh giá Razer Blade 15: Laptop gaming hoàn hảo, mỗi tội đau thận',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'Cùng ngắm cosplay Saber đẹp đến ngất ngây trong Fate/Extella',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'Game võ hiệp Wushu Chronicles chính thức có mặt trên Steam',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => '8 sự thật thú vị về series game nổi tiếng Call of Duty, toàn những con số nhức hết cả não',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => '10 Game mobile miễn phí hay nhất trên cả Android và IOS năm 2018 này',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'Sự trỗi dậy của eSports: môn thể thao hoàn toàn mới sinh ra từ công nghệ',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'EA tiếp tục khiến game thủ thất vọng, Battlefield 5 phải lùi ngày ra mắt',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'Bleach: Ulquiorra với Orihime Inoue, tình yêu tuyệt đẹp giữa ác quỷ và thiên thần',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'Điểm mặt gọi tên hệ thống phó bản của MU Strongest',
                'created_at' => date('Y-m-d H:i:s'),
            ],
            [
                'title'      => 'Những tác giả truyện kiếm hiệp nổi tiếng nhất với gamer Việt',
                'created_at' => date('Y-m-d H:i:s'),
            ],
        ];
        DB::table('news')->insert($arrayData);
    }
 
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('news');
    }
}

Chạy lệnh php artisan migrate để tạo ra bảng news trong CSDL

D:\xampp\htdocs\blog>php artisan migrate
Migration table created successfully.

Chú ý: Nếu bạn run lệnh php artisan migrate mà bị lỗi như sau :

Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQ
  L: alter table `users` add unique `users_email_unique`(`email`))

Thì cách fix như sau:Bạn sửa file D:\xampp\htdocs\blog\app\Providers\AppServiceProvider.php thành như sau:

<?php
 
namespace App\Providers;
 
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Schema::defaultStringLength(191);
    }
 
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Sau đó xóa table users và table migrations trong database rồi chạy lại lệnh php artisan migrate
Bước 3 : Tạo controller và model blog
Tạo controller blog:

php artisan make:controller BlogController

Tạo model:

php artisan make:model News

Bước 4 : Tạo route và view
Tạo route hiển thị danh sách tin tức và route phân trang :

Route::get('blog', 'BlogController@showBlog');
Route::post('paging', 'BlogController@paging');
Bạn thêm vào BlogController function showBlog hiển thị danh sách tin tức như sau:
public function showBlog(){
     return view('blog');
    }

Tạo view tên là blog.
Chèn thư viện DataTables và boostrap 3 vào:
Ở đây mình sử dụng CDN để chèn library DataTables vào website.Các bạn không thích dùng CDN thì có thể download library về chèn vào website.
Còn boostrap 3 các bạn có thể download ở đây Download
Sau khi download thư viện boostrap3 về các bạn copy bootstrap.min.js vào D:\xampp\htdocs\blog\public\js,copy bootstrap.min.css vào D:\xampp\htdocs\blog\public\css

<link rel="stylesheet" href="{{ URL::asset('css/bootstrap.min.css') }}">
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script type="text/javascript" src="{{ URL::asset('js/bootstrap.min.js') }}"></script>

Thêm code html hiển thị table :

<div class="container" style="margin-top: 100px">
        <div class="row">
             <div class="center-block">
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            <h3 class="panel-title">Demo phân trang laravel và datatable</h3>
                        </div>
                        <div class="panel-body p-none">
                            <table class="table data-table table-striped table-bordered">
                                <thead>
                                <tr>
                                    <th class="no-sort" style="width: 5%;">#</th>
                                    <th style="width: 75%;">Tiêu đề</th>
                                    <th style="width: 20%%;">Ngày tạo</th>
                                </tr>
                                </thead>
                                <tbody>
 
 
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
        </div>
    </div>

Thêm code js của datatables như sau:

<script type="text/javascript">
          var oTable = $('.data-table').DataTable({
              "oLanguage": {
                  "sLengthMenu": "Hiện _MENU_ Dòng",
                  "sSearch": "",
                  "sEmptyTable": "Không có dữ liệu",
                  "sProcessing": '',
                  "sZeroRecords": "Không tìm thấy dòng nào phù hợp",
                  "sInfo": "Đang xem _START_ đến _END_ trong tổng số _TOTAL_ mục",
                  "sInfoEmpty": "Đang xem 0 đến 0 trong tổng số 0 mục",
                  "sInfoFiltered": "(được lọc từ _MAX_ mục)",
                  "sInfoPostFix": "",
                  "sUrl": ""
              },
              "processing": true,
              "serverSide": true,
              "bAutoWidth": false,
              "order": [
                  [1, "desc"]
              ],
              "ajax": {
                  "url": "{{url('paging')}}",
                  "dataType": "json",
                  "type": "POST",
                  data: function(d) {
                    d._token = "{{csrf_token()}}";
                  }
              },
              "columns": [{
                  "data": "stt",
                  "bSortable": false
              }, {
                  "data": "title"
              }, {
                  "data": "created_at"
              }
              ]
          });
          oTable.on('draw.dt', function() {
              var info = oTable.page.info();
              oTable.column(0, {
                  search: 'applied',
                  order: 'applied',
                  page: 'applied'
              }).nodes().each(function(cell, i) {
                  cell.innerHTML = i + 1 + info.start;
              });
          });
    </script>

Code đẩy đủ của file template blog:

<!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">

        <title>Laravel Demo Paging with Datatables</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="{{ URL::asset('css/bootstrap.min.css') }}">
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script type="text/javascript" src="{{ URL::asset('js/bootstrap.min.js') }}"></script>
        <!-- Styles -->
        <style>
            
        </style>
    </head>
    <body>
        <div class="container" style="margin-top: 100px">
        <div class="row">
             <div class="center-block">
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            <h3 class="panel-title">Demo phân trang laravel và datatable</h3>
                        </div>
                        <div class="panel-body p-none">
                            <table class="table data-table table-striped table-bordered">
                                <thead>
                                <tr>
                                    <th class="no-sort" style="width: 5%;">#</th>
                                    <th style="width: 75%;">Tiêu đề</th>
                                    <th style="width: 20%%;">Ngày tạo</th>
                                </tr>
                                </thead>
                                <tbody>


                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
        </div>
    </div>
    <script type="text/javascript">
          var oTable = $('.data-table').DataTable({
              "oLanguage": {
                  "sLengthMenu": "Hiện _MENU_ Dòng",
                  "sSearch": "",
                  "sEmptyTable": "Không có dữ liệu",
                  "sProcessing": '',
                  "sZeroRecords": "Không tìm thấy dòng nào phù hợp",
                  "sInfo": "Đang xem _START_ đến _END_ trong tổng số _TOTAL_ mục",
                  "sInfoEmpty": "Đang xem 0 đến 0 trong tổng số 0 mục",
                  "sInfoFiltered": "(được lọc từ _MAX_ mục)",
                  "sInfoPostFix": "",
                  "sUrl": ""
              },
              "processing": true,
              "serverSide": true,
              "bAutoWidth": false,
              "order": [
                  [1, "desc"]
              ],
              "ajax": {
                  "url": "{{url('paging')}}",
                  "dataType": "json",
                  "type": "POST",
                  data: function(d) {
                    d._token = "{{csrf_token()}}";
                  }
              },
              "columns": [{
                  "data": "stt",
                  "bSortable": false
              }, {
                  "data": "title"
              }, {
                  "data": "created_at"
              }
              ]
          });
          oTable.on('draw.dt', function() {
              var info = oTable.page.info();
              oTable.column(0, {
                  search: 'applied',
                  order: 'applied',
                  page: 'applied'
              }).nodes().each(function(cell, i) {
                  cell.innerHTML = i + 1 + info.start;
              });
          });
    </script>
    </body>
</html>

Bước 5:Tạo paging:
Thêm vào BlogController function sau:

public function paging(Request $request)
    {
        $columns = array(
            0 => 'stt',
            1 => 'title',
            2 => 'created_at',
        );//dung de sap xep theo ten cot
 
        $totalData = News::count();
 
        $totalFiltered = $totalData;
 
        $limit = $request->input('length');//số lượng record hiển thị trong 1 trang,mặc định là 10
        $start = $request->input('start');
        $order = $columns[$request->input('order.0.column')];//lấy tên column sắp xếp
        $dir   = $request->input('order.0.dir');//desc or asc
 
        if (empty($request->input('search.value')))//lấy data từ ô search trong table
        {
            $news = News::offset($start)
                ->limit($limit)
                ->orderBy($order, $dir)
                ->get();
        } else {
            $search = $request->input('search.value');
 
            $news = News::where('id', 'LIKE', "%{$search}%")
                ->orWhere('title', 'LIKE', "%{$search}%")
                ->offset($start)
                ->limit($limit)
                ->orderBy($order, $dir)
                ->get();
 
            $totalFiltered = News::where('id', 'LIKE', "%{$search}%")
                ->orWhere('title', 'LIKE', "%{$search}%")
                ->count();
        }
 
        $data = array();
        if (!empty($news)) {
            foreach ($news as $item) {
 
                $nestedData['stt']         = '';
                $nestedData['title']      = $item->title;
                $nestedData['created_at'] = date('j M Y h:i a', strtotime($item->created_at));
                $data[] = $nestedData;
 
            }
        }
 
        $json_data = array(
            "draw"            => intval($request->input('draw')),
            "recordsTotal"    => intval($totalData),
            "recordsFiltered" => intval($totalFiltered),
            "data"            => $data,
        );
 
        echo json_encode($json_data);
    }

Bạn nào muốn dùng datatables với boostrap 3 thì chèn code này vào header

<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/responsive/2.2.3/css/responsive.bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/responsive/2.2.3/js/dataTables.responsive.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/responsive/2.2.3/js/responsive.bootstrap.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<!-- <script type="text/javascript" src="{{ URL::asset('js/bootstrap.min.js') }}"></script> -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
0 Shares

Leave a Reply

avatar
  Subscribe  
Notify of