没有编辑器插件的数据表内联编辑

Datatable inline editing without editor plugin

我正在使用 'editor' 数据插件 table 以下是代码:

数据table编辑定义为:

        editor = new $.fn.dataTable.Editor( {
        ajax: '/contact/' + Contact.id,
        table: "#contact-datatable",
        fields: [ {
                    name: "id",
                  }, {
                    name: "category",
                    type: "check",
                    options: [
                              { label: 'Science', value: "Science" },
                              { label: 'Maths', value: 'Maths' },
                              { label: 'Economics', value: 'Economics' },
                             ]
                 }
                    ................
              ]
    });

.....

$('#contact-datatable').on( 'click', 'tbody td:not(:first-child)', function (e) {
                editor.inline( this, { submitOnBlur: true } );
            } );

附加页面:当我们点击类别时,它会显示一个用于编辑的下拉菜单(使用编辑器插件)。

但问题是数据table的编辑器插件不是开源的,我的项目根本不允许付费插件。

谁能帮我在没有 'editor' 插件的情况下对数据 table 进行内联编辑?

以下是我在没有编辑器的情况下编写的代码:

Contact.dataTable = $('#contact-datatable').dataTable( {
        "ajax": {
                "url" : '/Contact/list/' + Contact.id,
                "dataSrc": function(check) {
                   check.id = Contact.id;
                   return json.check;
                  },
                },
            "responsive": true,
            "order": [],
            "columns": [
                { "data": "id"},
                { "data": "category" },
                { "data": "course" },
                ]
        } );

类别和课程将是一个下拉列表 - 并且必须进行内联编辑。下面附上一个页面示例。

我需要 'Category' 作为内联编辑器下拉菜单,然后会有一个保存按钮

数据表太棒了! SpryMedia 让我们免费使用它!尽管购买了 Editor Plugin,但我并不是 100% 确定我是否使用过它,但我很高兴我以某种方式为它的开发做出了贡献。我没有使用该插件的主要原因之一是因为我太瘦了,有一段时间买不起它,所以写了我自己的版本,这真的不那么困难。步骤很简单:

  • 检测对行的点击(您已经这样做了)
  • 从行中获取数据(一点也不难)
  • 用该数据填充表单(可能在模态中)
  • 提交表单后用新值更新服务器
  • 更新服务器后更新行

该插件使这一切变得简单,并允许您弄清楚后端。上面的步骤并不是那么困难,但除了编辑器插件之外,我还没有遇到可以为您完成所有操作的东西。完成这些步骤,您就会到达那里。

我编写了自己的内联编辑代码,使您可以编辑整行并定义您希望用户可编辑的列。

此处:https://github.com/sinhashubh/datatable-examples

执行此操作的步骤:

  1. 即使在点击时也能处理点击 row/cell。

            $("#dtexample tbody").on('click', 'tr td', function (e) {
                    RoweditMode($(this).parent());
                });
    
            function RoweditMode(rowid) {
                var prevRow;
                var rowIndexVlaue = parseInt(rowid.attr("indexv"));
                if (editIndexTable == -1) {
                    saveRowIntoArray(rowid);
                    rowid.attr("editState", "editState");
                    editIndexTable = rowid.rowIndex;
                    setEditStateValue(rowid, rowIndexVlaue + 2);
                }
                else {
                    prevRow = $("[editState=editState]");
                    prevRow.attr("editState", "");
                    rowid.attr("editState", "editState");
                    editIndexTable = rowIndexVlaue;
                    saveArrayIntoRow(prevRow);
                    saveRowIntoArray(rowid);
                    setEditStateValue(rowid, rowIndexVlaue + 2);
                }
            }
            function saveArrayIntoRow(cureentCells) {
                for (var k in EditRowData) {
                    $($(cureentCells).children('.' + k)[0]).html(EditRowData[k]);
                }
            } 
            function saveRowIntoArray(cureentCells) {
                $.each(ColumnData, function (index, element) {
                    if (element.Editable == true) {
                        var htmlVal = $($(cureentCells).children('.' + element.Name)[0]).html();
                        EditRowData[element.Name] = htmlVal;
                    }
                });
            }
            function setEditStateValue(td1, indexRow) {
                for (var k in EditRowData) {
                    $($(td1).children('.' + k)[0]).html('<input value="' + EditRowData[k] + '" class="userinput"  style="width: 99% " />');
                }
            }
    
  2. 输入任何内容后按回车,绑定回车输入(你可以根据需要将其更改为保存按钮。

            $("#dtexample tbody").on('keyup', 'input.userinput', function (e) {
                    if (e.keyCode == 13) {
                             updateRowData(this.parentNode.parentNode);
                    }
            });
    
  3. 更新函数以使用参数调用服务器。

            function updateRowData(currentCells) {
                var table = $("#dtexample").DataTable();
                var row = table.row(currentCells);
                rowid = currentCells.getAttribute('id');
                var UpdateRowData = [];
                $.each(ColumnData, function (index, element) {
                    if (element.Editable==true) {
                        UpdateRowData.push({
                            'pname': element.Name , 'pvalue': $($($(currentCells).children('.' + element.Name)).children('input')[0]).val()
                        });
                    }
                });
                console.log(UpdateRowData);
                UpdateRowData.push({ 'pname': 'rowid', 'pvalue': rowid });
                var parameter = "";
                for (i = 0; i < UpdateRowData.length; i++) {
                    if (i == UpdateRowData.length - 1)
                        parameter = parameter + UpdateRowData[i].pname + "=" + UpdateRowData[i].pvalue;
                    else
                        parameter = parameter + UpdateRowData[i].pname + "=" + UpdateRowData[i].pvalue + "&";
                }
                $.ajax({
                    type: 'POST',
                    url: '/WebService.asmx/UpdateTableData',
                    data: parameter,
                    success: function (data) {
                        var table = $('#dtexample').DataTable();
                        table.draw('page');
                    }
                });
            }
    

编辑器许可证让我很苦恼,所以我来这里是为了拯救你。

我是这样处理的:

  1. 创建 table 时,将 class 'editable' 添加到您要编辑的任何元素中

    example = new DataTable('#example', {
      columns: [
        { data: 'domain', name: 'domain' },
        { data: 'owner1', name: 'owner1', className: 'editable' },
        { data: 'owner2', name: 'owner2', className: 'editable'  },
        { data: 'description', name: 'description', className: 'editable' },
        { data: 'account_state', name: 'account-state' },
      ],
    });
    
  2. 当您 enter/exit td 时创建鼠标事件。我选择创建一个带有鼠标悬停的输入元素,因为我不希望到处都是实际的 html 输入

    // when the mouse enters a cell, create an editor. 
    $('#example').on('mouseenter', 'td.editable', function (e) {
      e.preventDefault() // I'm a noob, don't know what this means
      // I think there is some delay on when the events trigger 
      // so sometimes the cell still contains the input element and this check
      // prevents accidently creating another input element
      if (e.target.localName != 'input') {
        let row = e.target._DT_CellIndex.row
        let col = e.target._DT_CellIndex.column
        if (!e.target.children.length) {
            e.target.innerHTML = `<input id="${row}-${col}" type="text" class="editor" value="${e.target.innerHTML}">`
        }
      }
    })
    
    // when the mouse exits the editor, write the data into the table and redraw
    $('#example').on('mouseleave', 'td.editable', function (e) {
      e.preventDefault()
      if (e.target.localName != 'input') {
        let row = e.target._DT_CellIndex.row
        let col = e.target._DT_CellIndex.column
        data_table.cell(row, col).data(e.target.firstElementChild.value)
        data_table.draw() // up to you
      }
      else { // forces write when there is an event delay
        let [row, col] = e.target.id.split('-')
        data_table.cell(Number(row), Number(col)).data(e.target.value)
      }
      data_table.draw()
    })          
    

就是这样!

我的table最多2000条左右(肯定还能用),但是我 我确定有性能改进,我很想知道它们!