---
# System prepended metadata

title: DataTables開發紀錄
tags: [Javascript, DataTables除錯紀錄]

---

# DataTables開發紀錄
###### tags: `Javascript` `DataTables除錯紀錄`

# 除錯

## 錯誤訊息 `Requested unknown parameter X for row X, column X`
今天表格出了這種錯誤
但出錯完畢後還是可以正常呈現表格

![](https://i.imgur.com/44IFp1y.png)
```
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);
    }
  }
});

```