+2

Làm việc với jQuery Data Tables

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ì. Trong bài này, chúng ta sẽ đi qua một số điểm cơ bản của DataTables và cách sử dụng một vài tính năng cao cấp của nó.

Thiết lập DataTables

Bước đầu tiên đó là download library DataTables từ website về. Nếu bạn không muốn download file, bạn có thể sử dụng Microsoft CDN. Bạn nên thêm nó vào trong thư viện jQuery và nên sử dụng phiên bản mới nhất.

Quy tắc đặt tên

Trước khi tìm hiểu tiếp, chúng ta hãy xem quy tắc đặt tên của thư viện này. DataTables sử dụng Hungarian notation để đặt tên biến số, nói một cách đơn giản đó là thêm các tiền tố vào trước tên biến để thư viện này có thể hiểu được kiểu dữ liệu của biến.

n - Biến số biểu thị một node

o - Biến số biểu thị một object

a - Biến số biểu thị một array

s - Biến số biểu thị một string

b - Kiểu Boolean

f - Kiểu Float

i - Biến số biểu thị kiểu Integer

fn - Biến số biểu thị một hàm

Bạn có thể đôi lúc sẽ nhìn thấy nhiều tiền tố được sử dụng cùng một lúc, ví dụ như ao, sẽ biểu thị một mảng của các object.

Bắt đầu tìm hiểu

DataTables có thể làm việc với dữ liệu từ nhiều nguồn khác nhau. Nó có thể làm việc trực tiếp với một bảng HTML hoặc ta có thể sử dụng dữ liệu là một mảng khi đang khởi tạo. Hoặc nó có thể xử lý đối với dữ liệu đến tự các nguồn Ajax.

Trong phần này, chúng ta sẽ tạo ra một danh sách các website. Chúng ta sẽ bắt đầu với việc liệt kê ra một số tên website, sau đó ta sẽ thêm vào một số cột và tính năng khác. Ở đây, chúng ta có một bảng HTML với chỉ một cột duy nhất sử dụng để liệt kê danh sách tên của 3 trang web. Hãy cùng xem DataTables có thể làm gì với một thiết lập đơn giản.

<html>
<head>
  <link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css">
</head>
<body>
  <table id="example">
    <thead>
      <tr><th>Sites</th></tr>
    </thead>
    <tbody>
      <tr><td>SitePoint</td></tr>
      <tr><td>Learnable</td></tr>
      <tr><td>Flippa</td></tr>
    </tbody>
  </table>
  <script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.2.min.js"></script>
  <script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
  <script>
  $(function(){
    $("#example").dataTable();
  })
  </script>
</body>
</html>

Copy-paste đoạn code này vào một trang html và mở nó ra trên browser. Bạn sẽ nhìn thấy một bảng khá đẹp như sau.

datatablesfig1.png

Bây giờ ta đã hiểu được khả năng của DataTables và biết được ta có thể làm được gì với nó. Với thiết lập đơn giản nhất, ta có thể tìm kiếm tên của các Website ở ô tìm kiếm góc trên bên phải và có thể sắp xếp lại chúng bằng cách ấn vào tên column. Nếu bạn phải tự làm các tính năng này, sẽ rất khó khăn phải không.

Ở đây, đầu tiên ta đã thêm vào file DataTables CSS ở phía trên và Js ở phía dưới. $("#example").dataTable() sẽ tạo một DataTables trên một bảng với id là example.

Bây giờ, chúng ta muốn liệt kê nhiều trang web với nhiều thông tin hơn. Chúng ta sẽ làm việc với các thông tin như tên trang web, URL, kiểu web và ngày cập nhật cuối cùng, tuy nhiên ta sẽ xử lý trong một mảng JavaScript thay vì đối với một bảng HTML. Kiểu web có thể là blog, forum hoặc một marketplace. Ngày cập nhật cuối cùng có thể có giá trị null đối với những trang không phải là blog.

Ở đây ta muốn hiện ra chữ N/A thay vì giá trị null ở cột ngày cập nhật cuối, và làm cho URLs là một link có thể ấn vào được.

Đầu tiên ta sẽ tạo một bảng HTML, với các tên cột có sẵn, tuy nhiên không có nội dung bảng.

<table id="example">
  <thead>
    <tr><th class="site_name">Name</th><th>Url </th><th>Type</th><th>Last modified</th></tr>
  </thead>
  <tbody>
  </tbody>
</table>

Hãy đưa DataTables vào trong bảng này.

$("#example").dataTable({
  "aaData":[
    ["Sitepoint","http://sitepoint.com","Blog","2013-10-15 10:30:00"],
    ["Flippa","http://flippa.com","Marketplace","null"],
    ["99designs","http://99designs.com","Marketplace","null"],
    ["Learnable","http://learnable.com","Online courses","null"],
    ["Rubysource","http://rubysource.com","Blog","2013-01-10 12:00:00"]
  ],
  "aoColumnDefs":[{
        "sTitle":"Site name"
      , "aTargets": [ "site_name" ]
  },{
        "aTargets": [ 1 ]
      , "bSortable": false
      , "mRender": function ( url, type, full )  {
          return  '<a href="'+url+'">' + url + '</a>';
      }
  },{
        "aTargets":[ 3 ]
      , "sType": "date"
      , "mRender": function(date, type, full) {
          return (full[2] == "Blog")
                    ? new Date(date).toDateString()
                    : "N/A" ;
      }
  }]
});

Bây giờ bảng của chúng ta sẽ hiện như dưới đây. Chúng ta có một cột URL có thể ấn vào được, và cột ngày cập nhật mới nhất nhìn khá đẹp.

datatablesfig2.png

Chúng ta đã sử dụng json array với tuỳ chọn aaData của DataTables. Nếu bạn kiểm tra code, bạn sẽ thấy một tuỳ chọn là aoColumnDefs truyền tới DataTables, bên trong đó có mảng của một số Object. Giá trị của aoColumnDefs quyết định cách các cột được render trên bảng. Với property này, bạn có thể sửa đổi bất kỳ cột nào trong bảng, bằng cách chỉ ra giá trị của aTargets.

Giá trị trong mảng aTargets có thể là tên class được ghi ở tiêu đề cột hoặc là index của column (bắt đầu từ 0 từ trái qua phải, hoặc index âm từ phải qua trái) hoặc set giá trị "_all" để thiết lập với tất cả các cột trên bảng. "sTitle":"Site name" cho cột đầu tiên sẽ override tiêu đề của column đầu tiên.

Bạn có thể thấy, sort icon bị thiếu ở cột thứ hai, lý do là vì việc sort dựa trên URL không có nhiều ý nghĩa lắm. Bạn có thể disable nó đi bằng việc thêm vào bSortable:false cho column tương ứng. mRender là một tùy chọn mạnh, có thể dùng để thay đổi dữ liệu hiển thị. Tính chất ngày có thể được xử lý bằng nhiều cách. Khi sử dụng một giá trị integer, nó sẽ sử dụng như là một index của mảng data. Khi sử dụng một string, nó sẽ gọi tới json object có tên là string đó.

Các tính năng này trở nên đặc biệt hữu dùng khi ta hiển thị dữ liệu json trả về từ server. mRender cũng có thể là một hàm, và sẽ được gọi khi render mỗi cell của cột đó. Hàm này sẽ sử dụng 3 parameter, giá trị, kiểu và toàn bộ row, giá trị trả về của nó sẽ là giá trị hiển thị lên cell. Ở phần code bên trên, hàm của chúng ta tạo ra một link tới URL đó và trả về link đó.

Cũng giống như thế, đối với cột thời gian update cuối cùng, ta cũng kiểm tra giá trị của cell ở cột thứ ba, nếu nó là một blog, ta sẽ trả về date theo format định sẵn, nếu không sẽ trả về "N/A".

Attributes "sType" giúp ta chỉ ra type mong muốn của column đó, dùng để quyết định xem giá trị của cell sẽ được sort thế nào trong column. Mặc định, DataTables hỗ trợ 4 kiểu type: string, numeric, date và HTML. Bạn có thể mở rộng nó bằng cách định nghĩa một kiểu mỡi. Ở đây, ta chỉ ra rằng type là "date" vì thế nó sẽ sort dựa trên ngày tháng. Nếu ta không chỉ ra, nó sẽ coi như dữ liệu đó là String và sort, mặc dù có thể không có tác dụng gì cả khi sort theo string.

Server side processing

Ở ví dụ trên, chúng ta đã làm việc với một bảng thuần HTML và một mảng dữ liệu json được đưa trực tiếp vào phía client. Đôi khi dữ liệu có quá nhiều record và sẽ không phải là thông mình lắm nếu ta lấy hết tất cả dữ liệu đưa vào DataTables trong một lần. Thay vào đó, ta có thể dùng tính năng server-side processing của DataTables và chỉ lấy nhữ record đang cần hiển thị lên front-end.

Mỗi khi bảng được render, DataTables sẽ gửi một request với một số parameter lên server, bao gồm điểm bắt đầu, độ dài hiển thị, dữ liệu search, các cột được sắp xếp... Server có thể sử dụng chúng trong một câu query SQL để lọc ra dữ liệu và gửi lại cho phía client. DataTables cần một vài attributes ở json trả về để hiển thị chúng chính xác ở front-end. Đó là:

iTotalRecord - Số lượng các record trên bảng, trước khi lọc dữ liệu iTotalDisplayRecords - Số lượng các record trả về sau khi lọc dữ liệu sEcho - Một bản sao của sEcho được gửi từ client aaData - Mảng dữ liệu từ server

Một response json từ server có thể sẽ như sau:

{
    "iTotalRecords": 50,
    "iTotalDisplayRecords": 10,
    "sEcho":10,
    "aaData": [
        {"name": "Sitepoint", "url": "http://sitepoint.com", "editor" :{ "name" : "John Doe", "phone" : ["9191919", "1212121"], "email":[]}},
        {"name": "Flippa", "url": "http://flippa.com",  "editor": { "name": "Adam Smith", "email" : ["adam.smith@domain.com"], "phone":[] }}
    ]
}

Để render dữ liệu này, đầu tiên chúng ta sẽ tạo một bảng html với các tiêu đề của cột tương ứng.

$("#example").dataTable({
  "bServerSide": true,
  "sAjaxSource": "http://localhost/data_source.json",
  "aoColumns": [{
    "mData":"name",
    "sTitle": "Site name"
  },{
    "mData": "url",
    "mRender": function ( url, type, full )  {
      return  '<a href="'+url+'">' + url + '</a>';
    }
  },{
    "mData": "editor.name"
  },{
    "mData": "editor.phone"
  },{
    "mData":"editor",
    "mRender": function(data){
      return data.email.join("<br>");
    }
  }]
});

Ở đây, ta vừa ra lệnh cho DataTables tải dữ liệu từ server bằng cách thiết lập "bServerSide": true. Khi chọn bằng true, ta cần cung cấp cả nguồn để lấy dữ liệu bằng cách sử dụng property sAjaxSource. Trong dữ liệu json trả về từ server, mặc định DataTables sẽ tìm đến aaData để lấy dữ liệu hiển thị ở bảng. Bạn có thể override việc này bằng cách chỉ ra một tên attribute trong property sAjaxDataProp.

Trong trường hợp này, chúng ta sẽ lấy được một mảng của json object, và ta cần nối key nào cần hiển thị ở column nào. Ta đã sử dụng aoColumns thay vì aoColumnDefs. Cả 2 đều có cùng xử lý nhưng theo 2 cách khác nhau. Khi sử dụng aoColumns, độ dài của mảng cần phải bằng với số cột trong bảng HTML mà ta cần map cho mỗi cột.

Trong json response ở đây, trường editor là một object với các trường name, email và phone. “mData“: “editor.name” sẽ yêu cầu DataTables lấy property name của object editor. Chú ý rằng phoneemail là các mảng, và sẽ được tự động được nối vào sử dụng comma, hoặc ta có thể tự customer một hàm mRender để làm cho nó nhìn đẹp hơn.

Ngoài ra...

Bên cạnh các tính năng vừa nêu ra ở trên, DataTables còn cung cấp nhiều phương thức rất hữu dụng và ta có thể mở rộng nó bằng cách viết plugin của chính mình. Cũng có rất nhiều API đơn giản có thể dùng để điều chỉnh bảng sau khi được tạo ra.

var oTable =  $('#example'). dataTable();
$('#example').on('click', 'tr', function(){
	var oData = oTable.fnGetData(this);
	console.log(oData);
})

Đoạn code này sẽ log lại giá trị của dữ liệu trong row khi ta ấn vào đó. fnGetData sẽ lấy TR/TD node hoặc index của một row và trả về giá trị của row hoặc cell.

Kết luận

DataTables là một thư viện có đa dạng các tính năng cũng như có đủ sự mềm dẻo giúp ta thao tác với bảng và việc lên danh sách. Thư viện này cũng cung cấp nhiều thiết lập và API đơn giản. Rất khó để có thể diễn giải hết tất cả các tính năng mà nó cung cấp chỉ trong một bài viết, vì thế ở đây tôi chỉ giới thiệu qua với các bạn về những tính năng hữu dụng và được sử dụng nhiều nhất.

Tài liệu tham khảo

  1. https://www.sitepoint.com/working-jquery-datatables/
  2. https://datatables.net/

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí