Mình đã tích hợp datatables như thế nào vào ứng dụng php laravel

Chắc hẳn không còn ai xa lạ gì với datatables. một công cụ vô cùng hữu ích. Từ khi sử dụng nó mình cảm thấy tiết kiệm được khá nhiều thời gian và thậm chí mình không cần phải quan tâm nhiều đến search, filter, hay paginate nữa. Một công cụ tuyệt vời.

Giới thiệu

Package

Nếu bạn sử dụng laravel để development ứng dụng thì đây sẽ là một package khá hay https://github.com/yajra/laravel-datatables

Nó hỗ trợ toàn bộ cho phía Server side của bạn phiên bản PHP tối thiểu để sử dụng nó phải từ PHP 5.6.4 trở lên.

Installs

Cài đặt vô cùng đơn giản

$ composer require yajra/laravel-datatables-oracle

Package sẽ tự động install phiên bản mới nhất cho ứng dụng của bạn. Trong file config/app.php Hãy include các thư viện sau

providers

Yajra\Datatables\DatatablesServiceProvider::class

aliases

'Datatables' => yajra\Datatables\Datatables::class,

Ngoài ra nếu bạn muốn config cá nhân thì có thể publish file config của nó

$ php artisan vendor:publish

Vậy là xong các bước tích hợp package đã xong bây giờ mình sẽ đi tiến hành vào sử dụng nó như thế nào cho hiệu quả nhất.

Sử dụng

Server side

Ở phía server side mình đã thấy rất nhiều bạn sử dụng datatable nhưng chỉ sử dụng engines collectionEngine của nó mà không sử dụng eloquentEngine Sử dụng collection thì sẽ rất nhanh nhưng đôi khi các bạn vẫn muốn query trực tiếp trong database thì sao. Có nhiều câu query khó mà đôi khi collection không thể đáp ứng đủ. Ở Controller của mình trong method index mình sẽ viết như sau với Eloquent của mình là bảng Post

public function index(Request $request)
   {
       if ($request->ajax() && $request->has('datatables')) {
           $params = $request->all();
           $datatables = \Datatables::of(app(\App\Post::class)->query());
           $this->filterDatatable($datatables, $params, function ($query, $params) {
               if (array_has($params, 'category_ids') && $params['category_ids']) {
                   $query->byCategories($params['category_ids']);
               }
           });

           return $datatables->make(true);
       }

       return $this->viewRender();
   }

Trong method trên mình có gọi tới 1 method filterDatatable Method này nhiệm vụ của mình là để tách riêng việc tìm kiếm sang 1 method khác cho dễ quản lý. Method đó của mình như sau

//use Yajra\Datatables\Engines\EloquentEngine;

protected function filterDatatable(EloquentEngine $datatables, array $params, callable $callback = null)
   {
       return $datatables->filter(function ($query) use ($params, $callback) {
           if (array_has($params, 'keyword')) {
               $query->byKeyword($params['keyword']);
           }
           if (is_callable($callback)) {
               call_user_func_array($callback, [$query, $params]);
           }
       });
   }

Mình sử dụng callback mục đích là có thể tùy biến filter từ method index và method filterDatatable của mình sẽ được tái sử dụng lại nhiều lần ở đây các bạn thấy mình có dùng 2 scope trong eloquent là byKeywordbyCategories Controller của mình chỉ có vậy nếu các bạn để ý kỹ thì mình viết như vậy để tuân thủ quy tắc DRY Nhiệm vụ của mình đã hoàn thành mình đưa hết các câu truy vấn query vào trong model bởi vì nhiệm vụ của model là làm những việc đó chứ ko phải Controller

Scope in Eloquent

Trong file app/Post.php mình có 2 method scope cho việc filter như sau byKeyword

public function scopeByKeyword($query, $keyword)
   {
       return $query->where('name', 'LIKE', "{$keyword}%")
           ->orWhere('content', 'LIKE', "{$keyword}%");
   }

byCategories

public function scopeByCategories($query, $categories)
   {
       return $query->whereHas('categories', function ($query) use ($categories) {
           return $query->whereIn('ids', $categories);
       });
   }

Vậy là ở phía server side mình đã hoàn thành việc đổ dữ liệu và filter sử dụng eloquentEngine còn phía client side thì sao

Client side

Mình sẽ sử dụng bộ thư viện https://datatables.net/

<script src="vendor/datatables/js/jquery.dataTables.min.js"></script>
<script src="vendor/datatables-bs/js/dataTables.bootstrap.min.js"></script>

options datatable của mình sẽ như sau

$("#table-index").DataTable({
    processing: true,
    serverSide: true,
    responsive: true,
    searching: false,
    ajax: $.extend({
       url: '/server-side/post?datatable=1')
     }, {
     data: function(d) {
         d.keyword = $('input[name=keyword]').val();
     }
     })
});

Vậy mỗi khi cần filter dữ liệu client sẽ truyền params lên và server của mình sẽ query trực tiếp

Kết luận

Về thực tế mình thấy datatable rất hữu dụng. Nó hỗ trợ cho các bạn hầu hết tất cả mọi thứ từ phân trang cho đến tìm kiếm và nó còn cho performance cực kỳ cao. Nhiệm vụ của bạn cho phần filter gần như nó đã làm hết. Hi vọng với bài hướng dẫn cơ bản này sẽ giúp các bạn có thêm được nhiều kinh nghiệm hơn để làm việc với kỹ năng Read trong CRUD của mình.