# DataTables開發紀錄
###### tags: `Javascript` `DataTables除錯紀錄`
# 除錯
## 錯誤訊息 `Requested unknown parameter X for row X, column X`
今天表格出了這種錯誤
但出錯完畢後還是可以正常呈現表格

```
DataTables warning: table id=data_table - Requested unknown parameter '5' for row 0, column 5. For more information about this error, please see http://datatables.net/tn/4
```
本次遇到的錯誤是因為表格欄位與資料欄位對不上,或數量對不上
# 常用片段
## 基於父欄位的合併儲存格(上下合併)+重設流水號欄
欄位索引是從0開始
```javascript!=
$(document).ready(function () {
var table = $('#regionTable').DataTable({
order: [[1, 'asc'], [2, 'asc']], // 按洲別、國家排序
columnDefs: [{ orderable: false, targets: 0 }], // 流水號不給排序
drawCallback: function (settings) {
var api = this.api();
// 重設流水號欄 (第1欄,從0開始)
// 僅當前頁面用 { page: 'current' }
// 全部頁面用 { search: 'applied', order: 'applied' }
api.column(0, { page: 'current' }).nodes().each(function (cell, i) {
cell.innerHTML = i + 1;
});
// 合併儲存格
var rows = api.rows({ page: 'current' }).nodes();
// 合併「洲別」(第2欄)
mergeCells(api, rows, 1);
// 合併「國家」(第3欄)— 限定在同一洲底下
mergeCells(api, rows, 2, 1);
// 合併「縣市」(第4欄)— 限定在同一國家底下
mergeCells(api, rows, 3, 2);
// 合併「鄉鎮區」(第5欄)— 限定在同一縣市底下
mergeCells(api, rows, 4, 3);
}
});
/**
* 合併指定欄位的儲存格,僅當值相同且(若指定)父欄位也相同時才會合併。
*
* 此函式僅會合併「連續相同值」的儲存格,非相鄰的資料不會被合併。
* 常用於階層式資料(如:洲 → 國家 → 區域)的合併需求。
*
* @param {object} api - DataTables 的 API 物件。
* @param {HTMLElement[]} rows - 目前頁面的資料列集合,通常透過 `api.rows({ page: 'current' }).nodes()` 傳入。
* @param {number} colIndex - 欲合併的目標欄位索引(從 0 開始)。
* @param {number|null} [parentColIndex=null] - 父層欄位的索引,若為 null 表示不需考慮父層一致性。
*
* @example
* // 合併第 1 欄(洲別)
* mergeCells(table.api(), table.api().rows({ page: 'current' }).nodes(), 1);
*
* @example
* // 合併第 2 欄(國家),但僅當同屬同一洲時才合併
* mergeCells(table.api(), table.api().rows({ page: 'current' }).nodes(), 2, 1);
*/
function mergeCells(api, rows, colIndex, parentColIndex = null) {
let lastValue = null;
let lastParent = null;
let rowspan = 1;
let lastCell = null;
for (let i = 0; i < rows.length; i++) {
let row = rows[i];
let current = $('td', row).eq(colIndex).text();
let parent = parentColIndex !== null ? $('td', row).eq(parentColIndex).text() : null;
if (current === lastValue && (parentColIndex === null || parent === lastParent)) {
rowspan++;
$('td', row).eq(colIndex).hide(); // 隱藏重複的 cell
} else {
if (rowspan > 1 && lastCell) {
lastCell.attr('rowspan', rowspan);
}
lastValue = current;
lastParent = parent;
lastCell = $('td', row).eq(colIndex);
rowspan = 1;
}
}
if (rowspan > 1 && lastCell) {
lastCell.attr('rowspan', rowspan);
}
}
});
```