简体   繁体   中英

Change color of a cell after editing in datatable

I have a table in which I can edit and modify each cell.
I would like to highlight the cell that I modified.
At the moment I can only highlight the entire row but I don't have what I want to do.
I use createdRow to make the cells editable and get the modified row.

How can I do to highlight that modified cell?

var table  = $("#deploymentMap_table").DataTable({
    data: constructRaws(dataSet),//tbody
    paging:   false,
    searching: false,
    info: false,
    fixedHeader: true,
    scrollY: false,
    scrollX: false,
    responsive: false,
    dom: 't', //display only the table
    order: [[ 0, 'asc' ]],//order by 'service' col
    columnDefs:[
        {
            targets:'_all',
            render:function(data){
                if(data == null) {return ""
                } else {return data;}
            }   
        },
        { targets: [0,1], "width" : "200px"},
    ],
    columns: constructColumns(dataSet),//thead 
    dom: 'Bfrtip',
    // attribute classname (background color) for services
    rowCallback: function(row, data, index){
        if ( data.code == 1 ) {
            $('td', row).each( function ( value, index ) {
                if($(this).contents().first().text()){
                    $(this).addClass('td_colorCD');
                }
            } );
        }
        $(row).find('td:eq(0)').css('background-color', '#7f7f7f').css('color', '#fff').css('text-align', 'left');
        $(row).find('td:eq(1)').css('background-color', '#7f7f7f').css('color', '#fff').css('text-align', 'left');

        $.each(row.childNodes, function(i,value){
            if(value.innerText == "NoUP"){
                $(value).addClass('td_colorBSF');
            }
            else if(value.innerText){
                $(value).addClass('td_color');
            }
        })
    },
    // Make all cell editable
    createdRow: function(row, data, dataIndex, cells) {

        console.log(cells);
        let original

        row.setAttribute('contenteditable', true)
        row.setAttribute('spellcheck', false)

        row.addEventListener('focus', function(e) {
            original = e.target.textContent
        })

        row.addEventListener('blur', function(e) {

            if (original !== e.target.textContent) {

                $('td', row).removeClass();
                $('td', row).addClass('td_color_change');

                const r = table.row(e.target.parentElement)
                r.invalidate();

                var lign = e.target.innerText;
                lign = lign.split('\t');

                var nRow =  $('#deploymentMap_table thead tr')[0].innerText;
                head = nRow.split('\n\t\n');

                var newAR = mergeArrayObjects(head, lign);
                console.log("newAR", newAR);

                $(dataSet).each(function( index, values ) {
                    if(newAR.service[0].Services == values.service_name){
                        delete values.regions;
                        values.regions = newAR.region;
                        console.log(values);
                    }
                })
                console.log("dataset", dataSet);
            }
        })
    }
});

I think the easiest way to handle this is to replace your rowCallback with a DataTables delegated event .

Below is a simple example which would change the color of a specific cell when you leave that cell:

Step 1) The onblur event requires the cell to have a tabindex attribute. You can add this however you wish - but here is one way, in your existing code:

$.each(row.childNodes, function(i,value){
  $(value).attr('tabindex', i); // this line is new
  // your existing code goes here
})

Note - this could be improved as it repeats tab indexes across rows. But it illustrates the approach.

Step 2: Add a new onblur event listener, after the end of your DataTable definition:

$('#deploymentMap_table td').on('blur', function () {
  this.classList.remove("td_color");
  this.classList.add("td_color_change");  
} );

Step 3: The above code would need to be enhanced to include your edit-checking logic, which checks for an actual cell value change.

You can get the "before" cell values using this:

table.cell( this ).data();

And the "after" cell values using this - which gets the value from the HTML table (the DOM node), not from DataTables:

table.cell( this ).node().textContent;

The updated listener would be something like this:

$('#deploymentMap_table td').on('blur', function () {
  var cellValueStart = table.cell( this ).data();
  var cellValueEnd = table.cell( this ).node().textContent;
  //console.log( cellValueStart );
  //console.log( cellValueEnd );
  if (cellValueEnd !== cellValueStart) {
    table.cell( this ).data(cellValueEnd);
    this.classList.remove("td_color");
    this.classList.add("td_color_change");
  }
} );

The table.cell( this ).data(cellValueEnd) command updates the cell in DataTables so that it matches the value you typed into the HTML cell. If you do not do this, then the data in the DataTables object (behind the scenes) will be out-of-sync with the data in the HTML table (what you see on your screen).

Warning: This approach is basic. It does not cover the case where a user may do the following:

  1. Edit a cell from "A" to "B".
  2. Leave the cell, so it is highlighted.
  3. Return to the cell and edit it back from "B" to "A".
  4. Leave the cell again.

In this case, the cell will remain highlighted.

One way around this is to capture the original state of every cell when you first load the table - and then check each edit against the value in the original data. This can be done, if needed - but is outside the scope of this question. But it also depends on what you need to do with the data, after you have finished editing it. If this is important to you, then it may be worth asking a new question for that specific problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM