datatables表格行內編輯的實現

datatables表格行內編輯的實現

Datatables是一款jquery表格插件,它是一個高度靈活的工具,靈活就意味着很多功能需要自己去實現,比如說行內編輯功能。

Datatables自己是沒有行內編輯功能的,最簡單的是通過modal彈窗增改數據實現表格數據的修改,行內編輯我是通過操作DOM實現的,話不多說,先看效果圖如下:

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link href="bootstrap/css/bootstrap.css" rel="stylesheet">
    <link href="datatables/css/dataTables.bootstrap.min.css" rel="stylesheet">
    <style>
        body,
        html {
            margin: 0;
            padding: 0;
        }

        .gridArea {
            padding: 10px;
        }
    </style>
</head>

<body>
    <div class="gridArea">
        <table id="myGrid" class="nowrap table table-striped table-bordered table-hover table-condensed" cellspacing="0"
            width="100%">
            <thead>
                <tr>
                    <th>顯示名稱</th>
                    <th>屬性名稱</th>
                    <th>可爲空</th>
                    <th>關聯關係</th>
                    <th>屬性類型</th>
                </tr>
            </thead>

        </table>
    </div>


    <script src="jquery/jquery-1.12.3.min.js"></script>
    <script src="datatables/js/jquery.dataTables.min.js"></script>
    <script src="datatables/js/dataTables.bootstrap.min.js"></script>
    <script src="index.js"></script>
</body>

</html>
    
index.js
function createCombox(data) {
    var _html = '<select style="width:100%;">';
    data.forEach(function (ele, index) {
        _html += '<option>' + ele + '</option>';
    });
    _html += '</select>';
    return _html;
}

$(function () {
    var editTableObj;
    var comboData = {
        "2": ["是", "否"],
        "3": ["ManyToOne", "OneToMany", "無"],
        "4": ["String", "Long", "Integer", "Boolean", "Date", "當前實體"]
    };
    var setting = {
        columns: [
            { "data": "display" },
            { "data": "name" },
            { "data": "nullable" },
            { "data": "relation" },
            { "data": "type" }
        ],
        columnDefs: [{
            "targets": [0, 1],
            createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
                $(cell).click(function () {
                    $(this).html('<input type="text" size="16" style="width: 100%"/>');
                    var aInput = $(this).find(":input");
                    aInput.focus().val(cellData);
                });
                $(cell).on("blur", ":input", function () {
                    var text = $(this).val();
                    $(cell).html(text);
                    editTableObj.cell(cell).data(text)
                })
            }
        }, {
            "targets": [2, 3, 4],
            createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
                var aInput;
                $(cell).click(function () {
                    $(this).html(createCombox(comboData[colIndex]));
                    var aInput = $(this).find(":input");
                    aInput.focus().val("");
                });
                $(cell).on("click", ":input", function (e) {
                    e.stopPropagation();
                });
                $(cell).on("change", ":input", function () {
                    $(this).blur();
                });
                $(cell).on("blur", ":input", function () {
                    var text = $(this).find("option:selected").text();
                    editTableObj.cell(cell).data(text)
                });
            }
        }],
        data: [{
            "display": "1",
            "name": "",
            "nullable": null,
            "relation": null,
            "type": null,
        }],
        ordering: false,
        paging: false,
        info: false,
        searching: false,
    };
    editTableObj = $("#myGrid").DataTable(setting);
});

 

核心代碼如上,重點是columnDefs

官網上的說明是

和 columnsOption 參數很像,這個參數允許你給指定列設置選項,應用到一個或這多個列。而不像 columnsOption 需要每列都要定義

這個參數是一個列定義對象數組,通過使用 columnDefs.targets 選項,告訴Datatables是定義的是那一列,他可以是下列情況:

  • 0或者正整數-列從左到右是從0開始
  • 一個負數-列從右到左的索引(-1代表最後一列)
  • 一個字符串-將字符串和類名匹配列
  • 字符串"_all"-所有列

另外, targets可以同時指定多列,接受一個數組(比如 targets: [ -1, -2 ] )

createCell可以操作指定的DOM,它的五個參數分別是:td節點,單元格里的數據,正行的數據對象,單元格的行索引,單元格的列索引。

因爲序號列和單選佔據了0和1所以從2開始,target爲2和3的編輯形式是text,target爲4/5/6的編輯形式是select,其他的編輯形式也可以。

text形式的是點擊單元格的時候出現文本框並且手動讓其得焦,失去焦點的時候改變單元格的數據,這個很容易理解,唯一要注意的是,改變單元格數據的時候不能直接操作dom,那樣的話只是修改了頁面中節點內容,獲取表格數據的時候會發現表格數據還是沒有變化。修改單元格的數據要用到table.cell().data()這個方法,可以獲取和修改單元格的數據,cell的參數是要操作的單元格的dom節點,data不傳參數是獲取數據,傳入參數是修改數據。

select形式遇到了一個坑,就是在點擊單元格出現select下拉框後,發現下拉不下來,後來發現是因爲點擊select下拉框的時候觸發了事件冒泡,導致又執行了一遍點擊單元格的事件,所以select又重新生成了一遍導致展不開。所以給select的點擊事件里加了阻止事件冒泡 e.stopPropagation()。另外本來打算點擊單元格的時候出現下拉框並且自動展開,選擇一項後select消失並且把數據放進去,結果發現select標籤貌似不支持js展開,看了下其它網上的例子都是自己用div模擬的select來展開的,退而求其次就點擊單元格後再次手動點擊select讓它展開,以後有需求再用模擬的方式修改。

Datatables確實功能很多,自由度非常高,但是文檔很分散,以後要多多整理才能熟練起來。

最後附一下Datatables中文網鏈接:http://www.datatables.club/

demo已上傳github:https://github.com/gaiyabing/datatable-edit-inline

預覽地址:https://gaiyabing.github.io/datatable-edit-inline/index.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章