如何在 Tabulator 中仅使选定的行可编辑?

How to make only the selected row editable in Tabulator?

我在 React 中使用 Tabulator tables。

我要实现什么

我想强制用户一次只能编辑一行(但该行中的所有列):

  1. Select一行

  2. 单击“编辑”按钮 -> 仅编辑该行table(所有列)

  3. Edit/enter 通过内联编辑

    将值赋给那些 editable 列
  4. 单击“保存”-> 将更改保存到 table

我试过的:

使用 CellComponent 中的 edit() api 强制单元格编辑table。但这并没有打开单元格进行编辑(当我在单元格上调用 edit() 后单击单元格时没有任何反应。

const handleIfEditable = () => false; // force 

const columns: [
    { title: "ID", field: "id", editor: "input", editable: handleIfEditable },
    { title: "Name", field: "name", editor: "input", editable: handleIfEditable }
];

const selectedRowComponents = table.getSelectedRows();

const row = selectedRowComponents[0];
const cells = row.getCells();
    
cells.map(cell => cell.edit()) // trying to make all cells in row editable, didn't work (nothing happens)

这是我实现的。 这就是您要找的吗?

function formatter_EditButton(cell, formatterParams, onRendered){
    return "<div class='btn badge badge-pill badge-secondary'>Edit</div>";
}
function formatter_CancelButton(cell, formatterParams, onRendered){
   return "<div class='btn badge badge-pill badge-warning'>Cancel</div>";
}
function formatter_SaveButton(cell, formatterParams, onRendered){
   return "<div class='btn badge badge-pill badge-success'>Save</div>";
}
function formatter_DeleteButton(cell, formatterParams, onRendered){
   return "<div class='btn badge badge-pill badge-danger'>Delete</div>";
}

function cellClick_EditButton(e, cell){
  currentRow = cell.getRow()
  currentTable = cell.getTable()
  selectedRows = currentTable.getSelectedRows()
    if (selectedRows.length == 0) {
      for (i = 0; i < selectedRows.length; i++) {
        selectedRows[i].deselect()
        selectedRows[i].reformat()
      }
      currentTable.deselectRow()
      currentRow.select()
      currentRow.reformat()

      cells = currentRow.getCells()
      for (i = 0; i < cells.length; i++) {
        cells[i].setValue(cells[i].getValue())
      }
      currentTable.hideColumn("EditButton")
      currentTable.showColumn("CancelButton")
      currentTable.showColumn("DeleteButton")
      currentTable.showColumn("SaveButton")
    }
  }
function cellClick_CancelButton(e, cell){
  if (!cell.getRow().isSelected()){
    return
  }
  currentRow = cell.getRow()
  currentTable = cell.getTable()
  if (cell.getRow().isSelected()){
    //Cancel
    cells = currentRow.getCells()
    for (i = 0; i < cells.length; i++) {
      cells[i].restoreOldValue();
    }
    stopEditing(cell)
  }
}
function cellClick_SaveButton(e, cell){
  if (!cell.getRow().isSelected()){
    return
  }
  stopEditing(cell)
}
function cellClick_DeleteButton(e, cell){
  if (!cell.getRow().isSelected()){
    return
  }
  //Can use prompt to make them connfirm the name
  if(window.confirm("Delete the user "+cell.getData().FirstName+" "+ cell.getData().LastName+"?"))
  {
    stopEditing(cell)
    cell.getRow().delete()
  }
}
function stopEditing(cell){
  currentRow = cell.getRow()
  currentTable = cell.getTable()
  currentTable.deselectRow()
  currentTable.showColumn("EditButton")
  currentTable.hideColumn("CancelButton")
  currentTable.hideColumn("DeleteButton")
  currentTable.hideColumn("SaveButton")
  currentRow.reformat()
}

function isRowSelected(cell){
  return cell.getRow().isSelected()
}
function cellClick_FlipIfSelected(e, cell){
  if (cell.getRow().isSelected()){
    cell.setValue(!cell.getValue())
  }
}

var UsersTable = new Tabulator("#UsersTable",{
  index:"ID",
  ajaxURL:"/api/getUsersData",
  layout:"fitDataFill",
  layoutColumnsOnNewData:true,
  paginationSize:10,
  pagination:"local",
  selectable:false,
  initialSort:[
    {column:"FirstName", dir:"asc"},
    {column:"LastName", dir:"asc"},
    {column:"Active", dir:"desc"}
  ],
  columns:[
    {title:"Active", field:"Active", formatter:"tickCross", mutator: mutator_Active, cellClick:cellClick_FlipIfSelected, align:"center", resizable:false},
    {title:"ID", field:"ID"},
    {title:"Last", field:"LastName", editable:isRowSelected, editor:"input", resizable:false},
    {title:"First", field:"FirstName", editable:isRowSelected, editor:"input", resizable:false},
    {title:"Email", field:"Email", editable:isRowSelected, editor:"input", resizable:false},
    {title:"Phone Number", field:"PhoneNumber", editable:isRowSelected, editor:"input", resizable:false},
    {title:"Created", field:"CreatedAt", editable:isRowSelected, formatter:"datetime", resizable:false},
    {title:"Updated", field:"UpdatedAt", editable:isRowSelected, formatter:"datetime", resizable:false},
    {field:"EditButton",formatter:formatter_EditButton,cellClick:cellClick_EditButton, headerSort:false, align:"center", resizable:false},
    {field:"CancelButton", formatter:formatter_CancelButton,cellClick:cellClick_CancelButton, headerSort:false, align:"center", resizable:false,visible:false},
    {field:"SaveButton",formatter:formatter_SaveButton,cellClick:cellClick_SaveButton, headerSort:false, align:"center", resizable:false,visible:false},
    {field:"DeleteButton",formatter:formatter_DeleteButton,cellClick:cellClick_DeleteButton, headerSort:false, align:"center", resizable:false,visible:false},
  ]
})

你很幸运,这真的很简单你只需使用 editable 列定义 属性 和 isSelected Row Component

函数
//define editable check function
var selectedCheck(cell){
    return cell.getRow().isSelected();
}

...

//in column definition for an editable column
{title:"First", field:"first_name", editable:selectedCheck},