Layui表格行內動態編輯數據

前言

今天向大傢分享一些關於經典前端框架 layui 中的動態表格數據操作,結合 JQuery 動態編輯單元格中的數據,希望能幫助到有需要的人,加油,共勉!

樣式功能說明

初始化代碼

根據 Layui 開發文檔,我們能很容易寫出如下代碼,加載內置組件,動態表格數據填充:

layui.use(function () {
    let layer = layui.layer,
        element = layui.element,
        table = layui.table,
        form = layui.form;
    // 指定編輯字段
    const field = ['typeName'];
    // 表格加載數據
    table.render({
        elem: "#newsTypeTable",
        height: 522,
        url: serverBase + "newsType/all",
        parseData: function (res) {
            return {
                "code": res.code,
                "data": res.data.types,
                "count": res.data.count
            };
        },
        // 開啟分頁
        page: true,
        request: {
            pageName: 'offset',
            limitName: 'pageSize'
        },
        toolbar: `
            <div>
                {{# if(checkPermission(1, null)){ }}
                    <button class="layui-btn layui-btn-sm layui-btn-primary" lay-event="add">
                        <i class="layui-icon layui-icon-addition"></i>
                    </button>
                {{# } }}
                {{# if(checkPermission(3, null)){ }}
                    <button class="layui-btn layui-btn-sm layui-btn-primary" lay-event="batchDel">
                        <i class="layui-icon layui-icon-subtraction"></i>
                    </button>
                {{# } }}
            </div>
        `,
        defaultToolbar: [],
        cols: [
                [
                    {type: 'checkbox', fixed: 'left'},
                    {field: 'id', title: 'ID', sort: true, align: 'center'},
                    {field: 'typeName', title: '新聞類別', align: 'center'},
                    {title: '操作', fixed: 'right', width: 200, align: 'center', toolbar: '#myBar'}
                ]
        ],
        text: {
            none: '顯示個寂寞哦~'
        }
    });
});

說明

首先通過請求後臺數據,將請求到的數據通過數據解析賦值,註意:如果開啟瞭分頁,需要後端傳遞顯示的總條數,當打開頁面默認發送的分頁請求是 …?page=1&limit=10 ,通過 request 屬性改變傳遞的參數名,例如我的分頁請求就被改為 …all?offset=1&pageSize=10 。

開啟瞭 toolbar 之後,右邊默認的頭工具欄就會開啟,不需要則需要將 defaultToolbar 屬性值置空,而且當你自定義 toobar 時,HTML 標簽元素需放到 div 標簽之中方能生效,這個一個規定。

toobar 中使用 Layui 模版語法對當前管理員權限進行驗證,如果沒有該權限則不予以顯示。

通過 {type: ‘checkbox’, fixed: ‘left’} 開啟復選框,並將其固定到表格中的最左側。

操作欄中,通過 id 引入外部自定義 toolbar

<script type="text/html" id="myBar">
    <button class="layui-btn layui-btn-sm layui-btn-primary" lay-event="edit">
        <i class="layui-icon layui-icon-edit"></i>
    </button>
    <button class="layui-btn layui-btn-sm layui-btn-primary" lay-event="del">
        <i class="layui-icon layui-icon-delete"></i>
    </button>
</script>

添加監聽事件

監聽頭工具欄

table.on('toolbar(newsTypeList)', function(obj) {
    let checkStatus = table.checkStatus(obj.config.id);
    // 選中行數據
    let selectedData = checkStatus.data;
    if(obj.event === 'add') {
        // 跳轉到新聞類型添加頁面
        window.open('addNewsType.html', 'mainFrame');
    }else if(obj.event === 'batchDel') {
        if(selectedData.length > 0) {
            let ids = [];
            selectedData.forEach((targetRow) => {
                ids.push(targetRow.id)
            });
            layer.confirm(`確認刪除 ID[${ids}] 嗎?`, {title: '警告', icon: 0},
                function (index) {
                    $.ajax({
                        type: "DELETE",
                        contentType: "application/json;charset=UTF-8",
                        url: serverBase + "newsType/del",
                        data: JSON.stringify(ids),
                        dataType: 'json',
                        success: function (res) {
                            if (handleResponseData(res, layer)) {
                                // 成功刪除後,重新加載頁面
                                setTimeout(function () {
                                    location.href = 'newsTypeList.html';
                                }, delayTime);
                            }
                        }
                    });
                    layer.close(index);
                }
            );
        }else {
            layer.msg('請至少選擇一行', {icon: 3});
        }
    }
});

公用 js 文件中定義瞭 serverBase(請求後端基址)、delayTime(消息彈層延遲時間)以及封裝瞭對返回數據進行處理的函數 handleResponseData 。

到此,頭工具欄的兩個功能就實現瞭,還是比較簡單的,對吧?

監聽表格行工具欄

table.on('tool(newsTypeList)', function (obj) {
    // 獲得 lay-event 對應的值(也可以是表頭的 event 參數對應的值)
    var layEvent = obj.event;
    // 獲取該行數據對象
    var data = obj.data;
    switch (layEvent) {
        case 'edit':
            const row = obj.tr;
            const field_td = row.find(`[data-field$=${field[0]}]`);
            field_td.data('edit', true);
            row[0].onclick = function() {
                setTimeout(function () {
                    field_td[0].lastChild.onblur = function () {
                        row.find('[data-field$=typeName]').data('edit', false);
                    }
                }, 10);
            };
            break;
        case 'del':
            let ids = [];
            ids.push(data.id);
            layer.confirm(`真的刪除 ID => ${ids[0]} 所在行嗎?`, function(index) {
                //向服務端發送刪除指令
                $.ajax({
                    type: "DELETE",
                    contentType: "application/json;charset=UTF-8",
                    url: serverBase + "newsType/del",
                    data: JSON.stringify(ids),
                    dataType: 'json',
                    success: function (res) {
                        if (handleResponseData(res, layer)) {
                            setTimeout(function () {
                                // 刪除對應行(tr)的DOM結構,並更新緩存
                                obj.del();
                            }, delayTime);
                        }
                    }
                });
                layer.close(index);
            });
            break;
    }
});

行刪除很簡單,就是通過點擊所在行拿到刪除對象的 id ,向後端傳遞即可完成對應行的數據刪除。

行內實現點擊編輯按鈕進行編輯可謂有點難度瞭,首先你點擊按鈕後,要開啟約定字段的編輯,即點擊後就會出現一個輸入框,你可以對其進行修改更新操作,當輸入框失去焦點時,又要將剛剛的編輯入口關閉,也就是再一次點擊時不會二次出現輸入框。

// 開啟指定字段的編輯,關閉同理,參數傳入 false 即可
obj.tr.find(`[data-field$=${field[0]}]`).data('edit', true);

其中,field 規定編輯字段名,和 cols 屬性中 field 屬性值一致。

// 指定編輯字段
const field = ['typeName'];

通過 JQuery 中 find 函數找到單元格對應的標簽,再通過 data 函數增添 edit 屬性,並將其初始化為 true 值,相當於:{field: ‘typeName’, title: ‘新聞類別’, align: ‘center’, edit: true}

由於輸入框是在點擊對應的單元格後出現的,所以給單元格註冊一個點擊事件,點擊事件後不能立馬獲取到 input 輸入框,需要 DOM 結構更新存在延遲,需要給點延遲獲取的時間。

通過瀏覽器調試發現,該單元格 td 父元素中最後一個子元素就是 input ,添加失焦事件,當觸發時,關閉編輯入口,需重新按下按鈕開啟。

row[0].onclick = function() {
    setTimeout(function () {
        field_td[0].lastChild.onblur = function () {
            row.find('[data-field$=typeName]').data('edit', false);
        }
    }, 10);
};

監聽單元格

table.on('edit(newsTypeList)', function(obj) {
    let value = obj.value // 得到修改後的值
        , data = obj.data // 得到所在行所有鍵值
        , field = obj.field; //得到修改的字段
    let modifiedData = {id: data.id};
    modifiedData[field] = value;
    $.ajax({
        type: "POST",
        contentType: "application/json;charset=UTF-8",
        url: serverBase + 'newsType/update',
        data: JSON.stringify(modifiedData),
        dataType: 'json',
        success: function(res) {
            if(!handleResponseData(res, layer)) {
                setTimeout(function () {
                    location.href = 'newsTypeList.html';
                }, delayTime);
            }
        }
    });
});

最後,將修改後的對象傳入並發送更新請求,對於修改的值可於後臺進行校驗,修改失敗則刷新當前頁面。

結尾

到此這篇關於Layui表格行內動態編輯數據的文章就介紹到這瞭,更多相關Layui表格動態編輯內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet! 

推薦閱讀: