DATATABLE.JS 應用

是 jQuery Javascript 庫的插件。它是一種高度靈活的工具,針對處理table資料非常方便,只要引入此套件就有像是分頁、搜尋、排序…等功能,也提供多項客製化選項


官網 https://datatables.net/

因應,規劃設計使用此DataTables 作為TABLE的資料呈現

基本上是透過 GPT 或是克勞德AI 協助整理與教學,寫了一個基礎透過API處理該內容共用設置
因為上述AI 等他基本範例版本都比較早,萬幸是版本差異沒有使這些教學應用有太大差異性。
版本2.1的,自己額外去針對style做客製不要換行,會依據內容物是文字或是數字,若為數字就靠右

使用過程中發現,某些設計下使用 
因TD依據內容物判斷,寬度也是會再調整,導致與TITLE的TH會有錯位問題。
再次請克勞德2協助處理

我是搭配VUE3 使用 因此結構內混搭

<table id="tableshow" ref="tbHardware" class="table table-striped mb-0 data-table fs-10 w-100">
    <thead class="bg-primary-subtle">
        <tr>
            <th v-for="column in tableColumns" :key="column.data" v-html="column.title"></th>
        </tr>
    </thead>
</table>

    Remittedassets() {
        let params = this.quertable
        let RemittedUrl = '';
        this.tableRemittedlist = [ 
            {
                orderable: false,
                render: DataTable.render.select(),
                targets: 0, with: '30px'

            },
            { data: 'AAA', with: '110px', title: app.localized.localizedStrings['AAA'], orderable: true },
            { data: 'AAABB', with: '110px', title: app.localized.localizedStrings['AAABB'], orderable: true },
            {
                data: 'AAABBCC', with: '120px', title: app.localized.localizedStrings['AAABBCC'], render: function (data, type, row) {
                    return '<div class="text-wrap">' + data + '</div>';
                }, orderable: true
            },
            
        ],
            loadSelecDataTable($('#tbRemittedlist'), this.tableRemittedlist, RemittedUrl, params);
          
    },
共用部分
    <link href="~/lib/vendors/datatables.net-bs5/dataTables.bootstrap5.min.css" rel="stylesheet" />
    <link href="~/lib/vendors/datatables.net-select-bs5/select.bootstrap5.min.css" rel="stylesheet" />
    <script src="~/lib/vendors/datatables.net-select/dataTables.select.min.js"></script>
    <script src="~/lib/vendors/datatables.net-select-bs5/select.bootstrap5.min.js"></script>
async function loadSelecDataTable($table, columnsdata, apiUrl, params, buttons = []) {
    try {
        const mydata = await callAjax(apiUrl, 'POST', params);
        const dataLength = mydata['rows'].length;
        let enableSorting = dataLength > 10;
        //let scrollYn = 350;
        let scrollYn = dataLength <= 10 ? false : 300;  // 若數據少於15行,禁用 scrollY

        // 銷毀現有的 DataTable
        if ($.fn.DataTable.isDataTable($table)) {
            $table.DataTable().destroy();
        }

        var tableData = $table.DataTable({
            columnDefs: [
                { type: 'string', targets: '_all' }  // 設定所有列的類型為字符串,避免自動檢測數字類型
            ],
            autoWidth: false,  // 禁用自動寬度調整
            data: mydata['rows'],
            columns: columnsdata,
            order: [1, 'asc'],
            pageLength: 10,
            lengthMenu: [10, 20, 30, 50, 100, 200, 300],
            searching: enableSorting,
            ordering: enableSorting,
            paging: enableSorting,
            info: enableSorting,
            responsive: true,
            scrollX: true,  // 啟用橫向滾動
            scrollY: scrollYn,  // 動態設置 scrollY 的高度,根據數據行數來啟用或禁用
            //fixedColumns : { start: 2 },
            scrollCollapse: true,
            deferRender: true,  

            select: {
                style: 'multi',
                selector: 'td:first-child',
                headerCheckbox: 'select-page',
                info: false
            },
            order: [
                [1, 'asc']
            ], drawCallback: function (settings) {
                var api = this.api();
                var $table = $(api.table().node());
                var $scrollBody = $table.closest('.dataTables_scrollBody');
                var $scrollHead = $table.closest('.dataTables_scroll').find('.dataTables_scrollHead');

                if (dataLength!==0) {
                    
            
                // 確保表頭和內容的寬度一致
                $scrollHead.find('table').css('width', $table.outerWidth()+10);

                // 同步表頭和內容的水平滾動
                $scrollBody.off('scroll').on('scroll', function () {
                    $scrollHead.scrollLeft($(this).scrollLeft());
                });

                // 調整列寬並確保表頭和內容列寬一致
                api.columns().every(function () {
                    var column = this;
                    var columnIndex = column.index();
                    var headerCell = $(column.header());
                    var bodyCell = $table.find('tbody tr:first-child td:nth-child(' + (columnIndex + 1) + ')');
                    
                    // 設置最小寬度以確保內容不會被截斷
                    var minWidth = Math.max(headerCell.outerWidth(), bodyCell.outerWidth());
                    headerCell.css('min-width', minWidth + 'px');
                    bodyCell.css('min-width', minWidth + 'px');
                    
                    // 如果使用了 fixedColumns,確保固定列也保持相同寬度
                    if (api.settings()[0].fixedColumns) {
                        var fixedHeader = $table.closest('.DTFC_LeftWrapper').find('th:nth-child(' + (columnIndex + 1) + ')');
                        var fixedBody = $table.closest('.DTFC_LeftWrapper').find('td:nth-child(' + (columnIndex + 1) + ')');
                        fixedHeader.css('min-width', minWidth + 'px');
                        fixedBody.css('min-width', minWidth + 'px');
                    }
                });

                // 調整DataTables的內部尺寸
                    api.columns.adjust();
                }
            },
            initComplete: function (settings, json) {
                var api = this.api();
                var $container = $(api.table().container());
                
                // 添加一個 resize 監聽器,以在窗口大小改變時重新調整列寬
                $(window).off('resize.dataTable').on('resize.dataTable', function () {
                    api.columns.adjust();
                });

                // 初始調整
                api.columns.adjust();
            }
        });

        // 在分頁、排序、搜索後重新調整列寬
        tableData.on('page.dt order.dt search.dt', function () {
            tableData.columns.adjust();
        });

        // 添加一個小延遲來確保所有元素都已正確渲染
        setTimeout(function() {
            tableData.columns.adjust();
        }, 100);


    } catch (error) {
        console.error('獲取資訊時發生錯誤:', error);
        alertDialog({
            title: '提示',
            message: '失敗,請稍後再試',
            cancelText: '關閉',
            showOkButton: false,
            onOk: () => {
                console.log('執行確認操作');
                document.getElementById('alertModal').remove();
            }
        });
    }
};