framework
framework copied to clipboard
Grid Editing: no control on row editor enable disable based on row data
Note: was initially open on grid section and tomivirkki recommend to open here, on framework section.
Vaadin version – Release 8.1
PROBLEM – there is no support to enable/disable row editor based on row data.
Depending of row (binded) data a row must be editable or not ~ row edit must be set as enabled disabled. Simple example: totals rows must not be editable. Problem is described for buffered mode. Unbuffered mode is worse. More – if the row problem it is solved, we have also no problems to setup cols/cells as editable: we can set editor components directly. Also we have solved this aspect: <<Prevent edit on non editable column #9844 - pull request>>
Grid intention – to set various properties based on current row object. Now it is inconsistent:
- OK for style per cell – built-in support: setStyleGenerator(obj->colStyleSet(obj), where “obj” is the row object and colStyleSet() a custom function that change the style per cell
- NOT OK for properties as enable/disable row editor
DETAILS - Why enable/disable row editor does not work? We cannot always retrieve the current row when we enter in editing. The grid use two types of selection:
- Row selection (full row is highlighted in blue)
- Cell selection, that could be in other row then the selected row
- It is wrong that editing start will consider the current selected row the one of current selected cell.
The Grid offers an event for row selection change, that could be used to setup the properties for that row, but also for editing columns/cells
table.addSelectionListener(e -> OnSelChangeRow (e));
private void OnSelChangeRow(SelectionEvent<GridAssociatedObject> e) { if (e == null) return; Set<GridAssociatedObject> selected = e.getAllSelectedItems(); if (selected == null || selected.isEmpty()) { return; } GridAssociatedObject bean = selected.iterator().next();
/**
* try to enable/disable row editor depending on associated object
* values
*/
if (bean != null) {
if (getEditor().isOpen()){
getEditor().cancel();
}
getEditor().setEnabled(!bean.isTotal());
}
I do not want that total rows to be editable in any way – the editor will be disabled if the row is total row and reverse The problem is that I could also navigate with the arrows keys and:
- The current selected cell could be in other row then the selected row
- In this case, pressing ENTER or double click – will open the editor for that row, but there is no way to retrieve the row object for the row of the selected cell – no event available
IMPORTANT: in this case I cannot set not editable/not editable rows based on row associated object
PROPOSALS - The API must be consistent in managing rows and cells properties. Example of possible behavior fixes:
- Change row selection also when we navigate with the arrows (or at least provide a such working mode that could be enabled)
- Event/Listener for cell selection change – with the possibility to retrieve also the data object from the row of selected cell
- The current behavior where we can have distinct row selection and cell selection is unexpected for the user. Could be better if this feature will be isolated in two different working modes
EXAMPLE OF THE PROBLEM

In this grid, only the total row must be read-only. The associated row object have a isTotal property. The editor it is enabled/disable as f(isTotal) in row selection change listener (see above code and/or the attached example file at the end).
SCENARIO – select an editable row (we have change also the style – editable cells in yellow) – navigate with the arrow keys to the non-editable, total row and press Enter: the editor is set according to the selected row, not to the selected cell. So, we cannot setup the total row as read only
IMPORTANT
- there is no problem on setting style for a particular cell based on row associated object. There is a built-in support with setStyleGenerator(obj->colStyleSet(obj).
- Grid need to be consistent and provide support for cell settings based on row data also for enable/disable, and not only for style
We can attach also full example code, but it is trivial.
We have also a custom solution, but we cannot extend some framework private members. I can comeback with details
Hm... how about grid.addOpenListener((e) -> if (isBadBean(e.getBean())) { grid.getEditor().cancel(); }}? I've used this workaround for a long long time now (extended Grid to have open/close events back in 7 when it didn't have them).
Not a solution but for provided example, would it be easier to just make the total row as a GridFooter?
@pwilkin editor.addOpenListener instead of grid.addOpenListener.
Can you give instructions how to add close editor event?
Actually method mentioned by @pwilkin does not work with latest Vaadin versions, see https://github.com/vaadin/framework/issues/11002
There is a partial workaround in case un-buffered editor is used, one can use https://vaadin.com/directory/component/gridfastnavigation-add-on