I have created a Handsontable and added conditional formatting to the table by assigning a specific cell renderer to each cell based off the value in the table column 'MIN_REMAINING_LIFE'. As per the instructions on the Handsontable website.
https://docs.handsontable.com/0.31.2/demo-conditional-formatting.html
And this works fine. My table rows change color depending on the value in the 'MIN_REMAINING_LIFE' column. However, when I go to overwrite another css property (making the row bold in this case) in any of these rows with a renderer already assigned. Nothing happens. The renderer will not update its value. I have provided my code which attempts to update the renderer on double click below.
var addDblClick = function (tableName, hot) {
hot.view.wt.update('onCellDblClick', function (row, cell) {
var selectedRow = hot.getSelected()[0];
addHighlightRow(hot, selectedRow);
});
}
var addHighlightRow = function (hot, selectedRow) {
if (selectedRow != null) {
var columnTotal = hot.countCols();
for (var i=0;i<columnTotal;i++) {
hot.getCellMeta(selectedRow, i).renderer = selectedRowCellRenderer
}
hot.render();
}
}
var selectedRowCellRenderer = function (instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.color = 'black';
td.style.fontWeight = '800';
}
I have also created a fiddle of this particular issue. See link below.
https://jsfiddle.net/JoshAdams/w8amwLvb/
You can replicate the issue by following the screenshots below.
So my question is. How can I update the "Bold" property (or any css property for that matter) of the row but still maintain the current conditional formatting renderer applied to the cell?
Related
I have two variations of code, each variation has a desired behavior, and an undesired behavior... But I don't understand why this is happening, or how to combine them to get both desired behaviors. (I've tried different variations of if/else statements trying to get both of the desired behaviors in one code, but I'm unsuccessful so far.
Variation 1: http://jsfiddle.net/crashvector/q81m7sab/15/
Correct behavior: You can select a row, change the drop down that appears, (the drop down value writes to the table) and you can deselect the row. (The check-uncheck column updates from a 1 to a 0.)
Undesired behavior: You can select a row, and then immediately deselect it. The check-uncheck column updates from 1 to 0, BUT the drop down doesn't write it's current value to the table and disappear.
}).on('deselect', function (e, dt, type) {
var dt_indexes = dt[0]
if (type === 'row') {
$.each( dt_indexes, function ( index ) {
var row = dataTable.row( dt_indexes[index] );
if(!Category && !Category.length) {
writeCell($(row.node()).find('select'));
};
toggleDataAndDraw(row, type, 0);
} );
}
dataTable.draw();
});
var writeCell = dropdown => {
var currentRow = dataTable.row(dropdown.closest('tr'));
var rowData = currentRow.data();
rowData.Category = dropdown.val();
$(currentRow.node()).find('td:eq(6)').html(
currentRow.data().Category
);
currentRow.draw();
};
Variation 2: http://jsfiddle.net/crashvector/q81m7sab/16/
Correct behavior: You can select a row, and then immediately deselect it. The check-uncheck column updates from 1 to 0, the drop down value writes to the table and disappears.
Undesired behavior: You can select a row, change the drop down that appears, (the drop down value writes to the table) and you can deselect the row. BUT the check-uncheck column DOESN'T update from a 1 to a 0.
}).on('deselect', function (e, dt, type) {
var dt_indexes = dt[0]
if (type === 'row') {
$.each( dt_indexes, function ( index ) {
var row = dataTable.row( dt_indexes[index] );
//if(!Category && !Category.length) {
writeCell($(row.node()).find('select'));
//};
toggleDataAndDraw(row, type, 0);
} );
}
dataTable.draw();
});
var writeCell = dropdown => {
var currentRow = dataTable.row(dropdown.closest('tr'));
var rowData = currentRow.data();
rowData.Category = dropdown.val();
$(currentRow.node()).find('td:eq(6)').html(
currentRow.data().Category
);
currentRow.draw();
};
END GOAL One function that has both correct behaviors and neither undesired behavior.
From your jsFiddle "Variation 1"... Simply change the condition (on line #222):
if(!Category && !Category.length) {
to:
if($(row.node()).find('select').length){
So it will execute writeCell() if the <select> is still present when the user is unchecking the row.
I prepared a custom renderer for Handsontable in angular 5 but i can not find a way to register the renderer.I can not find any function like 'registerRenderer'.Renderer function is specified below
coverRenderer (instance, td, row, col, prop, value, cellProperties):any
{
var escaped = Handsontable.helper.stringify(value),
button;
button = document.createElement('BUTTON');
button.setAttribute("name","Edit");
//button.onclick = this.editFood(value);
Handsontable.dom.addEvent(button, 'click', () => {
this.editFood(value);
});
Handsontable.dom.empty(td);
td.appendChild(button);
return td;
}
When i load the table it show error like "No registered renderer found under "coverRenderer" name". How can i register the renderer . I am using angular 5
After hours of tries, I did not found a way to register a new renderer. So I tried, when declaring the renderer of the table (I use columns object), something like this.
In my html I have:
<hot-table [data]="data" [colHeaders]="true" [columns]="columns"></hot-table>
In my component this portion of code
columns: object[] = [
{ data: 'data.rowName', readOnly: true, renderer: this.rowRendering},
{ data: 'data.baseInitialMargin'},
]
rowRendering(instance, td, row, col, prop, value, cellProperties) {
console.log("Rendering row ");
Handsontable.renderers.TextRenderer.apply(this, arguments);
if(row % 2 == 0) {
td.style.backgroundColor = '#F5F5F5';
} else {
td.style.backgroundColor = 'white';
}
}
And it works fine for me, I see the pair rows of my column with a different color. After a lot of blasphemy!
in your template you should write
<hot-column (data="{{row}}", title="{{row}}",[renderer]="tableOptions.options.renderer" )></hot-column>
I have a Handsontable which contains values and i need apply number format like $0,0.00 . Using the below code i am able achieve it but if i apply renderer to the cellproperty the cell changes with the new style by overwriting the previous cell format.Please tell what mistake i am doing
Code
function inHeadRenderer(instance, td, row, col, prop, value, cellProperties) {
Handsontable.TextCell.renderer.apply(this, arguments);
td.style.textAlign="left"
td.style.paddingLeft="1%";
td.style.fontWeight = 'bold';
td.style.fontSize="10px";
td.style.fontFamily= 'verdana';
td.style.background = '#FCFFFA';
td.style.color = '#0B610B';
}
cells: function (row, col, prop) {
if($("#handsontable").handsontable('getData')[col,row][num_cols-1] ==="Inflow"){
cellProperties={
type: 'numeric',
format:'0,0.00',
language: 'en'
}
return cellProperties;
}
I want to apply style for the formatted cell Properites
Renderer gets triggered every time changes are made to cell. That is the reason for overriding of formats.
Update
http://jsfiddle.net/hU6Kz/3519/ is the working code for your reference.
Correction.
Included the type in renderer
inHeadRenderer=function(instance, td, row, col, prop, value, cellProperties) {
Handsontable.NumericCell.renderer.apply(this, arguments);
td.style.textAlign="left"
td.style.paddingLeft="1%";
td.style.fontWeight = 'bold';
td.style.fontSize="10px";
td.style.fontFamily= 'verdana';
td.style.background = '#FCFFFA';
td.style.color = '#0B610B';
cellProperties.type = 'numeric';
};
I am building a pretty combobox with checkboxes and conditional entries. Everything works out alright, except for two features that I cannot figure out how to implement.
1) I would like to move the label inside the combobox, make it shift the values to the right, and appear in a slightly gray color.
2) I would like the value to ignore certain entries (group headers) selected. Those entries are there for functionality only - to select/unselect groups of other entries.
The entire project is in the zip file. You don't need a server, it's a client base app. Just download the archive, unpack, and launch app.html in your browser.
http://filesave.me/file/30586/project-zip.html
And here's a snapshot of what I would like to achieve.
Regarding your second issue, the best way I see is to override combobox onListSelectionChange to filter the values you don't want:
onListSelectionChange: function(list, selectedRecords) {
//Add the following line
selectedRecords = Ext.Array.filter(selectedRecords, function(rec){
return rec.data.parent!=0;
});
//Original code unchanged from here
var me = this,
isMulti = me.multiSelect,
hasRecords = selectedRecords.length > 0;
// Only react to selection if it is not called from setValue, and if our list is
// expanded (ignores changes to the selection model triggered elsewhere)
if (!me.ignoreSelection && me.isExpanded) {
if (!isMulti) {
Ext.defer(me.collapse, 1, me);
}
/*
* Only set the value here if we're in multi selection mode or we have
* a selection. Otherwise setValue will be called with an empty value
* which will cause the change event to fire twice.
*/
if (isMulti || hasRecords) {
me.setValue(selectedRecords, false);
}
if (hasRecords) {
me.fireEvent('select', me, selectedRecords);
}
me.inputEl.focus();
}
},
And change your onBoundlistItemClick to only select and deselect items in the boundlist not to setValue of the combo:
onBoundlistItemClick: function(dataview, record, item, index, e, eOpts) {
var chk = item.className.toString().indexOf('x-boundlist-selected') == -1;
if ( ! record.data.parent) {
var d = dataview.dataSource.data.items;
for (var i in d) {
var s = d[i].data;
if (s.parent == record.data.id) {
if (chk) { // select
dataview.getSelectionModel().select(d[i],true);
} else { // deselect
dataview.getSelectionModel().deselect(d[i]);
}
}
}
}
},
Regarding your first issue, it is easy to add the label using the displayTpl config option. But this will only add the text you need, without any style (grey color, etc). The combo is using a text input, which does not accept html tags. If you don't need the user to type text, than you may want to change the combo basic behavior and use another element instead of the text input.
As in examples a new row is added when you type something into one of the cells of last row. How is it possible to add new row only after all cells in this new row are valid to the validator rules of columns ?
Here's a working snippet. It doesn't stop row from being added but it runs all validations on a new row and forces user to enter all missing values.
First define validateRow function (ideally it should be put in SlickGrid namespace):
function validateRow(grid, rowIdx) {
$.each(grid.getColumns(), function(colIdx, column) {
// iterate through editable cells
var item = grid.getDataItem(rowIdx);
if (column.editor && column.validator) {
var validationResults = column.validator(item[column.field]);
if (!validationResults.valid) {
// show editor
grid.gotoCell(rowIdx, colIdx, true);
// validate (it will fail)
grid.getEditorLock().commitCurrentEdit();
// stop iteration
return false;
}
}
});
}
Then invoke it in onAddNewRow binding func (or after adding a item to Array if you're not using DataView):
grid.onAddNewRow.subscribe(function (e, args) {
dataView.addItem($.extend({
id: dataView.getLength()
}, args.item));
validateRow(args.grid, args.grid.getActiveCell().row);
});
SlickGrid doesn't support that.