tbd_
tbd_

Reputation: 1248

How to make only the selected row editable in Tabulator?

I'm using Tabulator for tables in React.

What I want to implement

I want to force users to only edit one row at a time (but all columns in that row):

  1. Select a row

  2. Click EDIT button -> makes only that row editable (all columns)

  3. Edit/enter values to those editable columns via inline edit

  4. Click SAVE -> saves changes to the table

What I've tried:

Using the edit() api in CellComponent to force the cell to be editable. But that didn't open the cell for editing (nothing happens when I click on the cell after calling edit() on the cell.

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)

Upvotes: 1

Views: 3919

Answers (2)

Oli Folkerd
Oli Folkerd

Reputation: 8348

You are in luck, this is really easy you can just use the editable column definition property and the isSelected function on the 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},

Upvotes: 4

Mike Schmidt
Mike Schmidt

Reputation: 385

Here is what I have implemented. Is that what you are looking for?

Users Table Users Table Edit

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},
  ]
})

Upvotes: 4

Related Questions