async applyBackgroundColor(color: string): Promise<void> {
this.backgroundColor = color;
return new Promise<void>((resolve, reject) => {
try {
this.selected.forEach(selection => {
Object.keys(selection).map(rowIndex => {
const selectedRow = selection[parseInt(rowIndex)];
console.log('row selected:', rowIndex);
selectedRow.forEach(async cell => {
const [row1, col1, value1] = cell;
const cellMeta = this.handsontableInstance.getCellMeta(row1, col1);
const cellRenderer = this.handsontableInstance.getCellRenderer(cellMeta);
// const cellStyles = window.getComputedStyle(this.handsontableInstance.getCell(row1,col1)!);
// console.log(cellStyles.background);
const newRenderer = function (instance: any, td: any, row2: any, col: any, prop: any, value: any, cellProperties: any) {
if (typeof cellRenderer === 'function') {
cellRenderer(instance, td, row2, col, prop, value, cellProperties);
td.style.background = color;
}
}
this.setCustomRenderer(row1, col1, newRenderer, this.handsontableInstance);
if (this.activeSheet.rows) {
const cell = this.activeSheet.rows[row1].cells.find(m => m.row === row1 && m.col === col1);
if (cell && cell.cellStyles.fill && cell.cellStyles.fill.bgColor) {
cell.cellStyles.fill.bgColor.argb = color;
}
}
Then, I filter by the cells that have renderer applied
public saveJSON() {
// GET Handsontable DATA
const data = this.hot.getData();
const cellsWithValue = data.filter((row: any[]) => {
return row.some(cell => cell !== null && cell !== undefined && cell !== '');
});
// GET HOT Configuration
const settings = this.hot.getSettings();
const meta = this.hot.getCellsMeta();
const cellsWithRenderer = meta.filter((cellMeta: Handsontable.CellProperties) => {
return cellMeta.hasOwnProperty('renderer');
});
// Modify meta elements to include the renderer directly
const modifiedMeta = cellsWithRenderer.map((cellMeta: Handsontable.CellProperties) => {
return {
...cellMeta,
renderer: cellMeta.renderer?.toString() // Convert the renderer function to a text string to be exported as JSON
};
});
console.log('values',cellsWithValue);
console.log('renderers',cellsWithRenderer);
console.log('settings',settings);
// Combine data and configuration into a JSON object
const jsonData = {
name: this.activeSheet.name,
data: cellsWithValue,
meta: modifiedMeta // Include renderer function definitions directly in each meta element
};
// Convert the JSON object to a string
const jsonString = JSON.stringify(jsonData);
this.sheetService.saveTemplate(jsonString).subscribe((response: any) => {
});
//UNCOMMENT THIS IF YOU WANT TO CREATE A DOWNLOADABLE FILE
// this.fileService.saveJsonToFile(jsonString, fileName)
}
This generates a JSON with the cell data and the applied renderers. For example:
-
0: ColumnMeta2
-
col: 0
-
prop: 0
-
renderer: ƒ (instance, td, row2, col, prop, value, cellProperties)
-
row: 0
-
visualCol: 0
-
visualRow: 0
-
fixedColumnsLeft: (…)
-
fixedColumnsStart: (…)
-
layoutDirection: (…)
-
[[Prototype]]: TableMeta
-
length: 1
-
[[Prototype]]: Array(0)
In another instance where I try to obtain this JSON to create an instance of Handsontable with the loaded template I am using:
const data = JSON.parse(this.templates[0].jsonData);
const settings = {
data: data.Data, // Use the data provided in the JSON
meta: [] as Handsontable.CellMeta[], // Defines the columns based on the JSON data
};
this.hot = new Handsontable(mainElement, {
minRows: 50,
minCols: 8,
width: 'auto',
licenseKey: 'non-commercial-and-evaluation',
});
if(settings.data.length > 0){
this.hot.loadData(settings.data);
}
settings.meta.map((meta: any) => {
console.log(meta);
const rendererFunction = eval(`(${meta.renderer})`);
this.hot.setCellMetaObject(meta.row,meta.col,{ renderer: rendererFunction });
console.log('after apply render: ', this.hot.getCellMeta(meta.row,meta.col));
this.hot.render();
})
Any suggestions?
Basically what I’m trying to do is:
- define a template using handsontable,
- In another instance, be able to load that template, with data and styles
When creating the template, the render works excellent, but when “exporting” it and loading it in another instance it stops working