Ajax 載入的列詳細資訊
顯示 DataTable 中某列的詳細資訊是一項很受歡迎的功能。它允許使用者輕鬆存取和處理主表格視圖,同時也能以結構化的方式深入查看更詳細的資料。
DataTables 提供子列 API 方法 (row().child()
、row().child().show()
等),讓您可以輕鬆顯示此類詳細資訊列。甚至在本網站上也有一個簡單的範例。
這篇文章的主題是建立在該範例之上,描述如何處理一個簡單但常見的要求擴充:透過 Ajax 非同步載入子列的資料,而不是僅使用表格中已有的資料。
範例
下表顯示了我們將在本文中建立的範例。點擊顯示圖示將顯示「載入中」訊息,然後由從伺服器以 Ajax 載入的資料取代。在這個演示中,伺服器端腳本中添加了人工的兩秒延遲,以便您可以看到載入訊息,然後被載入的資訊取代。
姓名 | 職位 | 辦公室 | 薪水 | |
---|---|---|---|---|
姓名 | 職位 | 辦公室 | 薪水 |
設定
這篇文章的大部分內容實際上是關於 DataTable 的基本設定,因為最終的實作可能出乎意料的簡單。如果您已經熟悉建立 DataTable,請跳到「Ajax 請求」部分。
基本 DataTable
讓我們從頭開始,建立一個具有 Ajax 來源資料且使用 物件作為資料來源的 DataTable
var table = $('#myTable').DataTable( {
ajax: '/api/staff',
columns: [
{
className: 'details-control',
orderable: false,
data: null,
defaultContent: ''
},
{ data: "name" },
{ data: "position" },
{ data: "office" },
{ data: "salary" }
],
order: [[1, 'asc']]
} );
請注意,表格中的第一欄被指定了一個類別,並且僅顯示一個空字串(即什麼都沒有!)作為其資料值。這是為了我們可以將該儲存格用於開啟/關閉圖示,讓使用者點擊它來顯示詳細資訊列。
事件處理程式
我們可以附加以下事件監聽器來執行開啟/關閉操作
$('#myTable tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row( tr );
if ( row.child.isShown() ) {
row.child.hide();
tr.removeClass('shown');
}
else {
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
在上面的程式碼中,我們使用 row().child.isShown()
來檢查該列是否已顯示子列。如果是,則使用 row().child.hide()
隱藏它;如果不是,則使用 row().child().show()
建立它。
這正是整篇文章圍繞的後者函數!在最簡單的情況下,您可以將字串傳遞給 row().child()
,它會在子列中顯示該字串,但重要的是,您也可以傳遞一個節點(或包含節點的 jQuery 物件),它將顯示在表格中。這使得一旦 Ajax 請求完成後更新文件變得非常容易,只要我們保留對該節點的參考。
Ajax 請求
我們的目標是建立一個 Ajax 請求,其回應將決定在詳細資訊列中顯示的內容。在載入資料時,我們希望向使用者顯示「載入中」訊息,以便他們知道正在發生某些事情。我們可以透過使用 Javascript 的一個非常強大的功能來做到這一點,我們經常將其用作 Javascript 開發人員,但並非總是賦予其名稱:閉包。
您會在事件處理程式程式碼的第 10 行注意到我們呼叫了一個自定義定義的函數,稱為 format
(使用您想要的任何函數名稱!),並傳入列資料 - 我們想要做的是讓它返回一個包含載入訊息的元素給 DataTables,以便立即顯示,但同時建立一個 Ajax 請求,該請求會在資料載入後更新該元素。
function format ( rowData ) {
var div = $('<div/>')
.addClass( 'loading' )
.text( 'Loading...' );
$.ajax( {
url: '/api/staff/details',
data: {
name: rowData.name
},
dataType: 'json',
success: function ( json ) {
div
.html( json.html )
.removeClass( 'loading' );
}
} );
return div;
}
基本上就是這樣!子列中顯示的內容完全取決於您自己,因為它只是一個 div
容器元素。您可以使用動畫來顯示它,插入另一個 DataTable,任何您喜歡的內容!這裡的關鍵是返回 div
以由子列呈現,同時也使用 Ajax 和閉包來非同步填充該 div
。