Get cell attributes

Tags: #<Tag:0x00007f8b23510198>

Hello All,

I using following code to set attribute to all the cells in handsontable:

function myRenderer(instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
if (value) {
	//td.id = value.id;
	td.setAttribute("unique-id", value);
}

}
Handsontable.renderers.registerRenderer('myRenderer', myRenderer);

 hot.updateSettings({
cells: function (row, col, prop) {
          if(col === 0 || col === 1 || col === 2 || col === 3 || col === 4 || col === 5 || col === 6 || col === 7) {
    				var cellProperties = {};
    				cellProperties.renderer = "myRenderer";
    				return cellProperties;
           }
    }
});

Now I need to access this unique-id of the cell, on beforeChange event below:

hot.addHook('beforeChange', function (changes, source) {
        if (source === 'loadData' || source === 'internal' || changes.length > 1) {
            return;
        }
        var row = changes[0][0];
        var prop = changes[0][1];
        var value = changes[0][3];
       var col = hot.propToCol('AId');
  // here I have row and col indexes, but I am not sure to get the attribute of that cell and use it to pass to ajax call I have to do. 

Please let me know how I can access the attribute of that cell which I set in renderer. Also I need to tell that I am using the merge cell feature as well, for duplicate data to be merged.

Hi @vanivkulkarni

Please find the example at https://jsfiddle.net/handsoncode/mn5t1f37/1/

I am using the getCell method to access a cell and then the getAttribute on the TD element that I received.

Hi @aleksandra_budnik,

Thanks for the answer, but as I mentioned in the question, I have merged cells. Due to which, the getCell method is returning undefined and getAttribute is throwing error.

Hi @vanivkulkarni

merged cells are areas of cells that are a second layer on the actual table.

If you could share an exact scenario I can check if there is any other solution.

Hi @aleksandra_budnik,
Below is the merge code I am using to merge the cells after the data is loaded:

function merge() {
    if (hot == null) {
        return;
    }
    var mergeCells = [], rowspan = 1, tempName = '';
    var data1 = hot.getData();
    var cols = 6;

    for (var j = 0; j < cols; j = j + 2) {
        for (var i = 0; i < data1.length; i++) {
            var cellData = hot.getDataAtCell(i, j);
            if (cellData === tempName) {
                rowspan += 1;
            }
            else {
                mergeCells.push({ row: i - rowspan, col: j, rowspan: rowspan, colspan: 1 })
                mergeCells.push({ row: i - rowspan, col: j + 1, rowspan: rowspan, colspan: 1 })
                rowspan = 1
            }
            tempName = hot.getDataAtCell(i, j);;
        }
    }
    return mergeCells;
} 

$.ajax({
            type: "POST",
            url: "LoadData",
            success: function (response) {
                label.text(response.data);
                dataToLoad = JSON.parse(response.sheetData);
                hot.loadData(dataToLoad);
                hot.loadData(dataToLoad);
                hot.updateSettings({ mergeCells: merge() });
                hot.render();
            },
            failure: function (response) {
                alert(response.responseText);
            },
            error: function (response) {
                alert(response.responseText);
            }
        });

There are 2 things which I need to perform, after the data is loaded.

  1. There should be autosave happening for every 1 min,
  2. Few cells are dependent on unique-id data for generating the next cell values.

For autosave, I am using the following code found in documentation of handsontable:

afterChange: function (change, source) {
            //send the changes for save
			clearTimeout(autosaveNotification);
			if (source === 'loadData') {
				return; //don't save this change
			}
            if (change !== null) {
                var arrayOfChanges = change;
				var dataToSend = {};
				// unmerge ...needs to be done here..... else all the common data is going as null 
				
				dataToSend.finalData = hot.getSourceData();
				dataToSend = JSON.stringify(dataToSend);
				autosaveNotification = setTimeout(function () {
					$.ajax({
						url: "SaveCurrentData",
						type: "POST",
						contentType: "application/json",
						dataType: "json",
						data: dataToSend,

						success: function (result) {
							dataToLoad = result.sheetData.result;
							dataToLoad = JSON.parse(dataToLoad);
							hot.loadData(dataToLoad);
							hot.loadData(dataToLoad);
						},

						error: function (xhr, resp, text) {
							console.log(xhr, resp, text);
						}
					});
				}, 1000);
            }
        }

For cells values which is dependent on unique-id following is code written:

beforeKeyDown: function (e) {
            var selection = hot.getSelected();
            var col = "";
            var row = "";
            if (lastChange) {
                row = lastChange.row;
                col = lastChange.col;
            }
            // ENTER
            if (e.keyCode === 13) {
                hot.alter('insert_row', row + 1);

                var prevValue = hot.getDataAtCell(row, col - 1); // this is null, so I tried unique-id, even that is null due to merged cell, td is hidden
                var cellProp = hot.getCellMeta(row, col - 1);
                var dataToSend = {};

                dataToSend.Value = prevValue;
                dataToSend.Column = cellProp.prop;
                dataToSend.Key = "ENTER";
                dataToSend = JSON.stringify(dataToSend);
                $.ajax({
                    url: "SaveChanges",
                    type: "POST",
                    contentType: "application/json",
                    dataType: "json",
                    data: dataToSend,

                    success: function (result) {
                        dataToLoad = result;
                        dataToLoad = JSON.parse(dataToLoad.data.result);
                        hot.loadData(dataToLoad);
                        hot.loadData(dataToLoad);
                        //need to check and call later whenever loaddata is called
                        hot.updateSettings({ mergeCells: merge() });
                        hot.render();
                        hot.selectCell(row + 1, col);
                        console.log(result);
                    },

                    error: function (xhr, resp, text) {
                        console.log(xhr, resp, text);
                    }
                });
            }
            else if (e.keyCode === 9) {

            }
            else if (e.keyCode === 27) {
                return;
            }
            lastChange = null;
        }

Can you check this demo https://jsfiddle.net/handsoncode/k6nf1a5p/? It works fine.I am missing something?

Hi @aleksandra_budnik,

When I try to post the entire sheet data, the columns which are merged, are showing as null, for remaining rows, only first row in merged cell shows data, due to which data array looks like below. Hence I was trying to use the attribute here. Will it be possible to unmerge before sending the whole sheet data to server?

[{ Id: A1, Name: A1Name, SId: B1, S1Name: B1Name},
 { Id: null, Name: null, SId: B2, S1Name: B2Name}]

Looks like I was making silly mistake of setting unwanted variables, due to which the values were getting passed as null. I have fixed that. Everything works. Thanks a lot for your help. Please close the issue.

Regards,
Vani

Thank you for an update.

I am happy that it works for you now.