2 Issues with handsontable 7.1.1

Tags: #<Tag:0x00007efc651fd0c0>

Our company has the pro edition of 7.1.1 and I am trying to do 2 things. The first thing is I am trying to do is highlight certain rows a color for the whole row based on a property. I saw a different article and copied a bit of the guys code from it but my issue is that the rows can skip around due to an archive filter we have in place, and now a new filter as well, that are added when creating the HOT using this code:

        const [columnToFilter] = columns.map((column, index) => ({ column, index }))
                    .filter(({ column }) => column.data === 'isDeleted');

                if (columnToFilter) {
                    this.grid.getPlugin('filters').addCondition(columnToFilter.index, 'eq', [false], 'conjunction');
                }

We also have a couple of frozen columns which are making this difficult as the first 2 columns are difficult to highlight as they’re frozen and the other rows will “randomly” become partially highlighted, usually the first 2 frozen rows, because of the missing/hidden rows from the filter that are in-between. Any way to get get the highlighting done accurately? Especially since the user can interact with the rows to trigger the highlighting affect while they are filtered.

The second issue I am having, I believe is also due to the filters we have in place before the table is even created. I removed the code above for 2 sets of filters and it seems to work in regards to not showing showing the error but I need it to work with the filters. I am trying to add and save a new row and, while it does save correctly, it is throwing an error for the user and I cant seem to find out why. It is happening when trying to update the table data and more precisely when I run the updateSettings() method. Here is the error I am encountering:

“Error saving new record: Cannot read property ‘Acceptance - Visual - Req’ of undefined”

Cannot read property ‘Acceptance - Visual - Req’ of undefined\n at ColumnSettings.cells (http://localhost:8080/js/main.bundle.js:3398:53)\n at Core.getCellMeta (http://localhost:8080/js/main.bundle.js:102641:43)\n at SamplesGenerator.dataFactory (http://localhost:8080/js/main.bundle.js:121917:32)\n at http://localhost:8080/js/main.bundle.js:182770:89\n at rangeEach (http://localhost:8080/js/main.bundle.js

Hi @rostamijonathan

I have a demo here that we can both test https://jsfiddle.net/handsoncode/9t6dcbw0/
It adds a background color to a newly added row. It works well on fixedColumnsLeft and stays with the row while filtering. Do you also use the setCellMeta to set up your highlight?

The error you get seems to be related to a call to cell meta of a cell that is not longer in the dataset. I would need a demo where this issue can be replicable to share more details.

ps. in v.8.0.0 we have introduced index mappers that fixed more than 150 issues related to incorrect index translations. Maybe that’s why in 7.1.1 you see some rows being highlighted randomly.

I believe that would probably work for newly added rows but the highlighting is based on a IsComplete column that wont apply to them. The rows that have this column set to true arent highlighted when loaded with the code in the fiddle and there is an action button per row that allows the user to set the row to complete/incomplete, and I would need the row highlighted when they set it to complete and when the grid is loaded for those rows that are set to complete.

We don’t need to worry about this other issue for now. I believe it corrected itself.

Could you send me over a demo that shows the process of highlighting with IsComplete that you use now? Maybe it’ll be better to work on that.

// Sets the background of completed rows to green and all others to white
function HighlightCompletedRows(hot: HandsontableGrid<Package>): void {
    hot.grid.updateSettings({
        cells: function (row, col,prop) {
        let cellProperties = {}
        let trimmedRows = hot.grid.getPlugin('trimRows').trimmedRows;
        let updatedIndex = row;
        let skipArchivedRow = false;
        let count = 0;

        if(trimmedRows && trimmedRows.length > 0){
            count = trimmedRows.filter(rowNumber => rowNumber < row).length;
            skipArchivedRow = trimmedRows.find(rowNumber => rowNumber == row);
        }

        if(skipArchivedRow)
            return cellProperties;

        updatedIndex -= count;
        
        let isComplete = hot.grid.getSourceDataAtRow(row)['isComplete'];
        let cell = hot.grid.getCell(updatedIndex,col);

        if(cell && isComplete) {
            // cell.style.background = '#54EE00';
            // cell.classList.add('green');
            // let frzTR = $('.handsontable.ht_clone_left').find('table tbody tr');
            // $(frzTR[updatedIndex]).find('td').addClass('green');
                debugger
            hot.grid.setCellMeta(updatedIndex, col, 'className', 'green')
        }
        return cellProperties;
    },
});
hot.render();
}

Sure thing. I am currently using this and it almost works but I have a few issues with it. When adding a new row it highlights one single cell in a different row, row 16 which is not set to complete, when sorted the highlights mess up and arent on the correct rows anymore. And while the majority of the columns will sort fine, the isComplete column of type checkbox wont sort correctly, im guessing due to the class implementation when using the setCellMeta?

I call that function in the class that creates the table and it is called right after table creation and when the SetComplete action button is activated. I do also have the 2 first columns frozen as well

UPDATE:

So far I have been able to get the row highlighting almost completely done correctly using the code below but come actions done in a row still cause it to highlight the wrong rows.

function HighlightCompletedRows(hot: Handsontable): void {
    let trimmedRows = hot.getPlugin('trimRows').trimmedRows;
    let rowCount = hot.getSourceData().length

    for (let index = 0; index < rowCount; index++) {
        let updatedIndex = index;
        let skipArchivedRow = false;
        let count = 0;

        if(trimmedRows && trimmedRows.length > 0){
            count = trimmedRows.filter(rowNumber => rowNumber < index).length;
            skipArchivedRow = trimmedRows.find(rowNumber => rowNumber == index);
        }

        if(skipArchivedRow)
            continue;

        updatedIndex -= count;
        let isComplete = hot.getSourceDataAtRow(index)['isComplete'];

        for (let i = 0; i < hot.countCols(); i++) {
            if(isComplete)
                hot.setCellMeta(updatedIndex, i, 'className', 'green')
            else
                hot.setCellMeta(updatedIndex, i, 'className', 'white')
        }
    }
}

and by calling it using these hooks:

afterfilter(){ 
  let hot = this;
   HighlightCompletedRows(hot)
},
afterUntrimRow(){ 
   let hot = this;
   HighlightCompletedRows(hot)
},
 afterTrimRow(){ 
     let hot = this;
      HighlightCompletedRows(hot)
 }

Was able to get the column sorting corrected using this columnSorting code:

{
        data: 'isComplete',
        header: 'Is Complete',
        type: 'checkbox',
        readOnly: true,
        columnSorting:{
            sortEmptyCells: true, // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table
            indicator: true, // true = shows indicator for all columns, false = don't show indicator for columns
            headerAction: true, // true = allow to click on the headers to sort, false = turn off possibility to click on the headers to sort
            compareFunctionFactory: function(sortOrder, columnMeta) {
                return function comparator(value, nextValue) {
                    debugger
                    return sortOrder == 'asc' ? value - nextValue : nextValue - value;
                };
            }
            
        }
    },

I think that at this point it might be the cause of the old index calculations without the index mapper.

Could you test v8 and let me know if it changes anything?