Search code examples
javascripthandsontable

Handsontable - afterChangeEvent how to detect when a whole row is deleted or added


I have create a custom function that executes on the afterChange cell event as per the instructions in the following Handsontable link.

https://docs.handsontable.com/0.15.0-beta3/Hooks.html

And I can perform actions based on each cell that is changed fine. As per the following code.

var hot = new Handsontable(container, {
    data: data(),
    minSpareRows: 1,
    rowHeaders: true,
    colHeaders: ['some array of headers']
    afterChange: function (changes, source) {
          onChangeHandler(this, changes, source);
        }
});

var onChangeHandler = function (hot_instance, changes, source) {
      var changesLength;
      var changePayloadtoServer = [];
      if (changes != null) {
        changesLength = changes.length;
      } else {
        changesLength = 0;
      }
      for (var i = 0; i < changesLength; i++) {
        var row = changes[i][0],
            col = changes[i][1],
            oldVal = changes[i][2],
            newVal = changes[i][3],

        var trigger = false

        // How to I determine that a whole row has been deleted/added here?
        // trigger = some check that a whole row has been deleted/added.

        if (trigger == true) {
            // Perform action on row deletion
          // i.e. CASCADE DELETE query on database

          // Perform action on row addition
          // i.e. INSERT INTO query on database
        } else {
          // Perform normal on cell change
          // i.e. UPDATE query on database

        }

      }

}

However, I cant figure out how to determine whether a entire row has been deleted or added in the changes. Given that the change data provided in this afterChange event is in the follow format:

[
{changedRowNumber, chnagedColumnName, oldCellValue, newCellValue}
, {changedRowNumber, chnagedColumnName, oldCellValue, newCellValue}
, {changedRowNumber, chnagedColumnName, oldCellValue, newCellValue}
, {changedRowNumber, chnagedColumnName, oldCellValue, newCellValue}
, ... etc.
]

I have created an example fiddle. See link below.

https://jsfiddle.net/JoshAdams/go898kq6/

Does anyone know how I can detect when a whole row is added or deleted?


Solution

  • What you're looking for is two other events also defined in the documentation:

    As you can imagine, you will have to defiene this two events in your handsontable configuration and not in your afterChange event.

    For example, see your JSFiddle edited :

    afterRemoveRow: function (index, amount) {
        console.log(amount + " row(s) removed starting line "+ index)
    },
    afterCreateRow: function (index, amount) {
        console.log(amount + " row(s) added starting line "+ index)
    },
    

    EDIT : Based on your comment, I made an example for the case you want; knowing when every value from a row became empty after a change. You can find a new simplified JSFiddle here containg the following afterChange event definition :

    hot.addHook('afterChange', function(changes) {
      if (!changes) {
         return;
      }
      $.each(changes, function (index, element) {
        var 
        rowEmpty = true,
        row = element[0],
        currentRowArray = hot.getData(row,0,row,hot.countCols());
    
        for(var i=0; i<currentRowArray[0].length-1; i++) {
          if(currentRowArray[0][i] != "") {
            rowEmpty = false;
            break;
          }
        }
    
        if(rowEmpty) {
          console.log("Row " + row + " is empty !");
        }
      });
    });
    

    Every time a change is made in a cell, the code within the event will check if there is at least one cell on the same row which contain a value (and finish the event if it sees one). If not, it prints in console that the row is empty. Hence the result you're looking for is the boolean rowEmpty.

    Also, note two things :

    1. The jQuery function $.each allows you to make it works when a user empty two (or more) rows at the same time.

    2. The -1 in the condition of the for loop. If you want to compare the length of your array versus the number of columns, don't forget that the number of columns obviously don't start to count from 0. So if there is 6 columns, this will be column 0 to 5, hence the -1.