2017 年 10 月 24 日 星期二

編輯器中的佇列變更

當向使用者呈現可編輯的資料時,有時您(或最終使用者!)會希望將多個變更排隊,以便一次提交。Editor 的多行編輯功能可解決此問題,針對需要編輯的欄位讓它們都具有單一值,但您可能希望個別編輯列,然後批次提交它們。這也可以使用 Editor 完成,在本篇文章中,我將探討如何精確地實現此目的。

像往常一樣,讓我們直接進入一個範例 - 您將在這裡看到,當您編輯表格中的資料時,「儲存變更」和「捨棄變更」按鈕會被啟用。點擊「儲存變更」按鈕,所做的變更將會儲存到伺服器。點擊「捨棄變更」按鈕,您猜對了,所做的變更將會被捨棄,並且會還原原始資料。

名稱 薪資
名稱 薪資

架構

在我們討論用來建構此範例的程式碼之前,我想強調一些用於實現此功能的三個特定的函式庫特性

  1. Editor 的本機表格編輯功能 - Editor 1.6 使 Editor 可以直接更新表格中的資料,而無需提交到伺服器。
  2. Editor 的多行編輯 API - 以程式方式在單一請求中提交多列的資料。
  3. 自訂按鈕 - 允許我們定義按鈕來執行我們需要的任何操作 - 在此情況下,將資料提交到伺服器。

將這三者與一個簡單的陣列結合起來,該陣列包含已編輯列的列識別符,就能夠提供我們建立佇列編輯介面所需的一切。

最後一塊拼圖是我們需要兩個 Editor 實例 - 第一個將用於本機表格編輯(配置時不使用 ajax 選項),第二個將用於提交批次編輯的 Ajax 請求(配置時使用 ajax 選項)。

本機表格編輯

Editor 中的本機表格編輯只是定義一個 Editor,其中包含所需的欄位(fields)以及要編輯的目標表格(table)。將其與標準的 DataTable 設定結合起來,我們可以得到如下所示的東西

var editorOpts = {
    table: '#myTable',
    fields: [
        {
            label: 'First name:',
            name: 'first_name'
        },
        {
            label: 'Last name:',
            name: 'last_name'
        },
        // ...
    ]
};

// Local table editing instance
var localEditor = new $.fn.dataTable.Editor(editorOpts);

// Ajax editor instance
var ajaxEditor = new $.fn.dataTable.Editor(
    $.extend(true, {
        ajax: '../php/staff'
    }, editorOpts)
);

var table = $('#myTable').DataTable({
    ajax: '../php/staff',
    columns: [
        {
            data: null,
            render: function(data, type, row) {
                // Combine the first and last names into a single table field
                return data.first_name + ' ' + data.last_name;
            }
        },
        { data: 'position' },
        // ...
    ],
    select: true,
    layout: {
        topStart: {
            buttons: [
                { extend: 'create', editor: ajaxEditor },
                { extend: 'edit',   editor: localEditor },
                { extend: 'remove', editor: ajaxEditor }
            ]
        }
    }
});

請注意,Editor 選項已放置在一個名為 editorOpts 的物件中 - 這允許將同一個物件重複用於 localEditorajaxEditor 實例,因為它們之間的唯一差異是 ajax 選項(該選項使用 jQuery 的 $.extend() 方法新增到物件中)。

對於顯示在表格上方的編輯按鈕,localEditor 用於編輯,而 ajaxEditor 用於建立和刪除列(它們會立即提交 - 如果需要,您可以將它們分開排隊)。

按鈕

接下來,考慮「儲存變更」和「捨棄變更」按鈕。在這裡,我們只需要兩個自訂按鈕,將它們添加到 buttons 陣列中,如下所示

{
    text: 'Save changes',
    init: function () {
        this.disable();
    },
    action: function () {
        // ...
    }
},
{
    text: 'Discard changes',
    init: function () {
        this.disable();
    },
    action: function () {
        // ...
    }
}

請注意,兩者都定義了一個 init 函式,該函式用於預設停用其動作。這是因為我們只希望在使用者實際編輯一列或多列時才啟用它們。

因此,我們不僅需要在編輯列時啟用按鈕,還必須追蹤已編輯的列,因此當我們需要將它們提交到伺服器時,我們可以在不需要傳送表格中的每一列的情況下完成此操作。這可以使用一個簡單的陣列、buttons().enable() 來啟用按鈕,以及 postEdit 事件來了解何時應更新它們

// Array which will store the id's of the rows which have been locally edited (for later submission)
var changedRows = [];

editor.on('postEdit', function (e, json, data) {
    // Store the row id so it can be submitted with the Ajax editor in future
    changedRows.push( '#'+data.DT_RowId );

    // Enable the save / discard buttons
    table.buttons([3,4]).enable();
});

按鈕選擇器(button-selector[3,4] 表示應選擇索引 3 和 4(從 0 開始)中的按鈕,這是在 buttons 陣列中新增時它們的位置。

多行編輯

有了其他所有東西,我們現在可以提交資料或捨棄它。這在各個按鈕的 action 函式中完成(在上面顯示省略號的位置)。在提交操作的情況下,我們可以使用 edit() 以及我們的已編輯列陣列,然後使用 submit()。由於 Editor 的多行編輯功能,它可以根據需要從陣列提交多列

action: function () {
    // Submit the Ajax Editor without asking for confirmation
    ajaxEditor
        .edit( changedRows, false )
        .submit();
    
    // Clear out the saved rows and disable the save / discard buttons
    changedRows.length = 0;
    table.buttons([3,4]).disable();
}

最後一部分是捨棄按鈕,這只是一個清空 changedRows 陣列並再次停用按鈕的案例。還會呼叫 ajax.reload(),以從伺服器重新載入目前儲存的資料。如果您不希望進行此伺服器互動,您可以選擇將編輯的原始資料儲存在 initEdit 中,但是這是保持資料為最新狀態的最有效方法。

action: function () {
    this.ajax.reload();

    changedRows.length = 0;
    table.buttons([3,4]).disable();
}

結論

我們在這裡看到了如何透過 Editor 的較新功能和一些自訂按鈕,可以輕鬆建立佇列編輯介面。如果您想查看上述執行示範的完整 Javascript,您可以在這裡查看

我最近幾篇部落格文章都著重在 Editor 上 - 我下一篇將回到 DataTables!與往常一樣,如果您對此或 DataTables 的任何其他方面有任何疑問或建議,請隨時在論壇中發文。歡迎提供回饋意見。

祝您使用愉快!