Search code examples
jquerydatatables

Make all cells editable in DataTables


I am using datatables 1.10.12 and I am having a simple table being drawn with:

projectRevenue = $('#projectRevenue').DataTable({
    serverSide: true,
    processing: true,
    scrollX: true,
    stateSave: true,
    ajax: {
            url: "{!! route('listOfProjectsRevenueAjax',$project->id) !!}",
            type: "GET",
            dataType: "JSON"
        },
    columns: [
        { name: 'id', data: 'id' , searchable: false , visible: false },
        { name: 'year', data: 'year' , searchable: true , visible: true },
        { name: 'product_code', data: 'product_code' , searchable: true , visible: true  },
        { name: 'jan', data: 'jan' , searchable: true , visible: true },
        { name: 'feb', data: 'feb' , searchable: true , visible: true },
        { name: 'mar', data: 'mar' , searchable: true , visible: true },
        { name: 'apr', data: 'apr' , searchable: true , visible: true },
        { name: 'may', data: 'may' , searchable: true , visible: true },
        { name: 'jun', data: 'jun' , searchable: true , visible: true },
        { name: 'jul', data: 'jul' , searchable: true , visible: true },
        { name: 'aug', data: 'aug' , searchable: true , visible: true },
        { name: 'sep', data: 'sep' , searchable: true , visible: true },
        { name: 'oct', data: 'oct' , searchable: true , visible: true },
        { name: 'nov', data: 'nov' , searchable: true , visible: true },
        { name: 'dec', data: 'dec' , searchable: true , visible: true },

I would like to be able to edit the cells so that it will get updated in the database. For this I would need to have each with contenteditable set to true and to have a class for example update => for this, I add className: "update", but I don't know how to make it content editable.


Solution

  • You can make all cells in a DataTable editable this way :

    const createdCell = function(cell) {
      let original
    
      cell.setAttribute('contenteditable', true)
      cell.setAttribute('spellcheck', false)
    
      cell.addEventListener('focus', function(e) {
        original = e.target.textContent
      })
    
      cell.addEventListener('blur', function(e) {
        if (original !== e.target.textContent) {
          const row = table.row(e.target.parentElement)
          row.invalidate()
          console.log('Row changed: ', row.data())
        }
      })
    }
    
    table = $('#example').DataTable({
      columnDefs: [{ 
        targets: '_all',
        createdCell: createdCell
      }]
    }) 
    

    As you can see in this demo -> http://jsfiddle.net/w9hrnf63

    They key part is row.invalidate(). This updates the row data internally if and only if you are working with a DOM table or other static resource. If you are using serverSide processing invalidate() will just reset the cell content back to original. So execute your update request to the server instead of invalidate() above :

    cell.addEventListener('blur', function(e) {
      if (original !== e.target.textContent) {
        const row = table.row(e.target.parentElement)
        $.ajax({
          url: '/updateScript/',
          data: row.data()
        })
      }
    })