前端外掛之Datatables使用--下篇

運維咖啡吧發表於2019-08-14

工欲善其事,必先利其器

本系列文章介紹我在運維繫統開發過程中用到的那些順手的前端外掛,上一篇文章介紹了Datatables外掛的基本使用,這一篇文章作為上一篇的延續,會介紹Databases的一些高階用法,例如從不同的資料來源獲取資料、修改資料最終呈現方式、操作Dom改變頁面功能、開啟服務端資料處理等

資料載入

上篇文章中的所有資料都是直接渲染的html中的table資料,datatables還支援其他幾種資料來源,以方便實現更靈活的控制

從陣列中獲取

<table id="myTable-x" class="display" style="width:100%"></table>

$(document).ready(function() {
    var dataSet = [
      ["3","https://ops-coffee.cn","2018-07-03"],
      ["9","https://demo.ops-coffee.cn", "2019-08-06"],
    ];

    $('#myTable-x').DataTable({
        "data": dataSet,
        "columns": [
          { title: "Id" },
          { title: "Site" },
          { title: "Date" },
        ]
    })
});

data: 指定陣列

columns: 配置每一列的title

注意:從陣列中獲取資料一定要有表頭,如果沒有則可能會報下邊的錯:

Uncaught TypeError: Cannot read property 'aDataSort' of undefined

解決方法就是datatables新增columns配置,或者寫上table的thead

<table id="myTable-x" class="display" style="width:100%">
    <thead>
        <tr>
            <th>ID</th>
            <th>Site</th>
            <th>Date</th>
        </tr>
    </thead>
</table>

從物件中獲取

<table id="myTable-x" class="display" style="width:100%"></table>

$(document).ready(function() {
    var dataSet = [
      {"Id":"3","Site":"https://ops-coffee.cn","Date":"2018-07-03"},
      {"Id":"9","Site":"https://demo.ops-coffee.cn","Date":"2019-08-06"},
    ];

    $('#myTable-x').DataTable({
        "data": dataSet,
        "columns": [
          {"data": "Id", "title": "Id"},
          {"data": "Site", "title": "Site"},
          {"data": "Date", "title": "Date"},
        ]
    })
});

使用物件陣列,一定要配置columns的data,告訴DataTables每列對應的屬性,title配置可選,新增title會給表格新增表頭

從例項中獲取

$(document).ready(function() {
    function dataSet(id, site, date) {
      this.id = id;
      this.site = site;
      this.date = date;
    };

    $('#myTable-x').dataTable({
      data: [
        new dataSet("3", "https://ops-coffee.cn", "2018-07-03"),
        new dataSet("9", "https://demo.ops-coffee.cn", "2019-08-06"),
      ],
      columns: [
          {"data": "id", "title":"Id"},
          {"data": "site", "title":"Site"},
          {"data": "date", "title":"Date"}
      ]
    });
});

Ajax非同步獲取

Datatables還支援Ajax的方式非同步載入資料,簡單的方式是直接配置一個url地址即可

$(document).ready(function() {
    $('#myTable-x').dataTable({
        "ajax": 'sdata.json'
    });
});

ajax接收的資料可以是陣列或者物件,注意columns的配置,可以對應參考前文兩種格式資料的處理

前端外掛之Datatables使用--下篇

結果資料處理

上邊的table可以發現有個site列的內容是一個網址,如果我們想讓網址能夠點選該如何實現呢?可以利用columnsrender屬性對展示結果進行更改

$(document).ready(function() {
    $('#myTable-x').dataTable({
        "ajax": 'sdata.json',
        "columns": [
            {"data": "id", "title":"Id"},
            {
                "data": "site", 
                "title":"Site",
                "render": function (data, type, row) {
                  return '<a href='+data+' target="_blank">'+data+'</a>'
                }
            },
            {"data": "date", "title":"Date"}
        ]
    });
});

render後邊跟了個函式,每當資料表需要獲取列中某個單元格的資料時render函式都會執行,且函式可能會被執行多次,函式預設接收三個引數,意思分別是:

data: 單元格的具體資料,例如https://ops-coffee.cn

type: 標識了這一次呼叫的請求型別,會有filterdisplaytypesort

row: 這一行的完整資料來源,如果像Demo示例傳了物件資料,那麼可以通過row.site獲取到這一行site列的資料

拿到引數進行一系列的處理後可以通過return返回最終想要展示的內容

當然也可以通過columns在表格末尾新增一列以實現編輯、刪除的按鈕展示

"columns": [
    {"data": "id", "title":"Id"},
    {
        "data": "site", 
        "title":"Site",
        "render": function (data, type, row) {
          return '<a href='+data+' target="_blank">'+data+'</a>'
        }
    },  
    {"data": "date", "title":"Date"},
    {   
      "data": "id",
      "title": "操作",
      "render": function (data, type, row) {
        return '<a href="#update/'+row.id+'/" class="btn btn-warning btn-sm">編輯</a> ' +
               '<a href="#delete/'+row.id+'/" class="btn btn-danger btn-sm">刪除</a>'
      } 
    }   
]

最終呈現結果如下圖

前端外掛之Datatables使用--下篇

Dom操作

如果我不需要datatables顯示左上角的每頁顯示條數資訊,而要換成一個新增按鈕改怎麼做呢?這裡可以藉助datatables的dom來實現

預設情況下表格都會有左上角的每頁顯示條數、右上角的搜尋、左下角的表格資訊、右下角的分頁、中間的資料載入等待以及表格本身,這些都是datatables的DOM,它們實際上就是一個div包裹起來的select、input之類的html標籤,datatables中的每個DOM都與一個字母相對應,他們的對應關係如下:

l: length,代表左上角的每頁顯示條數控制元件

f: filtering,代表右上角的搜尋控制元件

t: table,代表表格本身

i: information,代表左下角的表格資訊控制元件

p: pagination,代表右下角的分頁控制元件

r: processing,代表中間資料載入等待提示控制元件

這些控制元件在datatables裡可以通過配置dom來控制他們的顯示位置,以及是否顯示,預設的顯示順序是lfrtip

$('#myTable-x').dataTable({
    "dom": 'lfrtip'
})

你如果不想顯示某個控制元件,可以通過去掉dom配置項裡對應的字母實現,同時Datatables支援四個自定義的標籤,通過這四個標籤可以方便的來修改DOM的展示

< > 尖括號就代表html裡的div

<"class"> 代表了新增了class的div

<"#id"> 代表了新增了id的div

<"#id.class"> 代表新增了id和class的div

我們想把右上角的每頁顯示條數控制元件換成新增按鈕的話可以這樣寫

$('#myTable-x').dataTable({
    "dom": '<"#add-btn.toolbar">frtip'
})

$("#add-btn.toolbar").html(
  '<button href="#add" class="btn btn-success btn-sm"> + 新增</button>'
)

遇到樣式問題,需要新增css

<style type="text/css">
  .toolbar {float:left}
</style>

這樣就完美實現了

前端外掛之Datatables使用--下篇

伺服器端處理

Datatables支援使用服務端進行資料處理,當開啟服務端資料處理後,Datatables將在頁面執行分頁、排序、搜尋等操作時向服務端發出Ajax請求,Ajax請求會傳遞許多變數給服務端,服務端接收到請求後根據變數的值對資料進行處理,處理完成按照固定的格式返回給前端頁面,頁面對返回的資料進行渲染提供給使用者檢視

開啟伺服器模式只需要兩個設定項serverSideajax

$('#myTable-x').dataTable({
    "serverSide": true,
    "processing": true,
    "ajax": '/api/site/data'
})

serverSide: 為true時表示開啟服務端處理模式

processing: 為true時會開啟資料處理中的提示,非必須

ajax: 指定伺服器端的地址,可以像上邊一樣是個字串,也可以像jQuery.ajax一樣作為一個物件使用,例如我想傳遞額外的引數(datatables預設會給後端傳遞許多的引數,下邊有講)給後端伺服器的話,可以這樣用

$('#myTable-x').dataTable({
    "serverSide": true,
    "processing": true,
    "ajax": {
        "url": "/api/site/data",
        "data": function (d) {
            d.type = 'ops-coffee';
        }
    }
})

data: 可以在傳送請求給後端時額外增加type=ops-coffee的引數

傳送到伺服器端的引數

當開啟服務端資料處理後,預設會給服務端傳遞許多引數,大概如下:

draw:繪製計數器,主要用來確保Ajax從伺服器端接收到的資料是對應同一次請求的
start:第一條資料的起始位置
length:每頁顯示的條數
search[value]:全域性的檢索關鍵字
order[i][column]:告訴伺服器哪些列是需要排序的,i為排序列的序號,下邊的i相同含義,注意i是從0開始的
order[i][dir]:告訴伺服器排序的方式"desc","asc"
columns[i][data]:columns上定義的data屬性值
columns[i][name]:columns上定義的name屬性值
columns[i][searchable]:告訴伺服器哪些列可以被搜尋
columns[i][orderable]:告訴伺服器哪些列可以進行排序
columns[i][search][value]:告訴伺服器某些列的具體搜尋條件

如果需要後臺分頁,那麼需要拿到startlength兩個引數做相應的處理,

如果有搜尋的內容,那麼需要拿到serch[value]引數做處理

服務端返回資料的格式

服務端需要返回datatables可以處理的資料格式,具體資料格式如下:

{
    "draw": 1,
    "recordsTotal": 7,
    "recordsFiltered": 7,
    "data": [
        {
            "id": 3,
            "site": "https://ops-coffee.cn",
            "date": "2018-07-03"
        },
        {
            "id": 9,
            "site": "https://demo.ops-coffee.cn",
            "date": "2019-08-06"
        }
        // 省略其他結果
    ]
}

draw: 客戶端呼叫服務端次數標識,客戶端傳過來是什麼原樣返回回去即可,無需修改

recordsTotal: 資料總條數,沒有過濾的資料總條數

recordsFiltered: 過濾後符合要求的條數,如果沒有搜尋引數那麼這個值與recordsTotal一致

data: 需要顯示的具體資料,json格式

API呼叫

Datatables提供了強大的API來處理表格上的資料,可以通過API新增資料到已經存在的表格,或者對已經存在的資料進行操作,API的型別非常豐富,詳細的資訊可以查閱官網,使用方法如下:

跳轉到頁

跳轉到第3頁:

var table = $('#myTable').DataTable()

table.page(2).draw(false)

page(2): page為分頁方法,後邊的2表示跳轉到第幾頁,可以是一個數字,也可以是firstnextpreviouslast這樣的字串,當為數字時要從0算起,例如示例中為2實際上是跳轉到了第3頁

draw(false): 對錶格進行重繪以實現表格更新的顯示,大多數的api操作都不會直接更新在頁面上,所以需要呼叫下draw,預設情況下重繪後分頁會被重置回到第一頁,當設定為false時分頁不會被重置

搜尋某列

搜尋第2列包含https://ops-coffee.cn的行

var tablx = $('#myTable').dataTable()

tablx.api().column(1).search('https://ops-coffee.cn').draw()

首先需要注意這個例子中的API呼叫使用了.api(),這是因為上一個例子在初始化時用了.DataTable()而這個例子初始化時用了.dataTable(),僅僅是d字母大小寫的區別而已,但意義確不同,前者直接返回API例項,後者返回的是jQuery例項

完整Demo

為了方便大家學習,我寫了個完整的demo,你可以線上檢視效果或下載程式碼應用到自己的專案中

線上Demo地址:https://demo.ops-coffee.cn/datatables/

Github原始碼地址:https://github.com/ops-coffee/demo/tree/master/datatables


掃碼關注公眾號檢視更多實用文章

相關文章推薦閱讀:

相關文章