SmartColumn.js: update event triggers too early
The requiresSave state of a table field is not correctly updated
if the value of a smart column is edited.
This bug was introduced by the commits trying to prevent flickering
(added about a month ago).
The update event must not be fired before the value and the status
are correct.
288929
diff --git a/eclipse-scout-core/src/table/columns/Column.js b/eclipse-scout-core/src/table/columns/Column.js
index 7e34e8e..4cea3e3 100644
--- a/eclipse-scout-core/src/table/columns/Column.js
+++ b/eclipse-scout-core/src/table/columns/Column.js
@@ -529,7 +529,11 @@
setCellValue(row, value) {
let cell = this.cell(row);
+ this._setCellValue(row, value, cell);
+ this._updateCellText(row, cell);
+ }
+ _setCellValue(row, value, cell) {
// value may have the wrong type (e.g. text instead of date) -> ensure type
value = this._parseValue(value);
@@ -541,7 +545,6 @@
}
cell.setValue(value);
- this._updateCellText(row, cell);
}
setCellTextDeferred(promise, row, cell) {
diff --git a/eclipse-scout-core/src/table/columns/SmartColumn.js b/eclipse-scout-core/src/table/columns/SmartColumn.js
index a92f203..a5f14e1 100644
--- a/eclipse-scout-core/src/table/columns/SmartColumn.js
+++ b/eclipse-scout-core/src/table/columns/SmartColumn.js
@@ -216,12 +216,32 @@
}
_updateCellFromValidEditor(row, field) {
+ // The following code is only necessary to prevent flickering because the text is updated async.
+ // Instead of only calling setCellValue which itself would update the display text, we set the text manually before calling setCellValue.
+ // This works because in most of the cases the text computed by the column will be the same as the one computed by the editor field.
+
+ // Clear error status first (regular behavior)
this.setCellErrorStatus(row, null);
- // Always set the text even if the value will be set
- // This prevents flickering when display text is updated async.
- // In most of the cases the text computed by the column will be the same as the one from the field.
- this.setCellText(row, field.displayText);
- this.setCellValue(row, field.value);
+
+ // Update cell text
+ // We cannot use setCellText to not trigger updateRows yet -> it has to be done after the value and row.status are updated correctly.
+ let cell = this.cell(row);
+ let oldText = cell.text;
+ let newText = field.displayText;
+ cell.setText(newText);
+
+ // Update cell value
+ // We cannot use setCellValue since it would add the update event to the updateBuffer but we need the row update to be sync to prevent the flickering
+ this._setCellValue(row, field.value, cell);
+
+ // Update row -> Render row, trigger update event
+ // Only trigger update row event if text has changed (same as setCellText would do)
+ if (row.initialized && oldText !== newText && cell.text === newText) {
+ this.table.updateRow(row);
+ }
+
+ // Ensure display text is correct (for the rare case that the column computes a different text than the editor field).
+ this._updateCellText(row, cell);
}
/**
@@ -235,9 +255,8 @@
return !!value;
}
- setCellValue(row, value) {
- super.setCellValue(row, value);
- let cell = this.cell(row);
+ _setCellValue(row, value, cell) {
+ super._setCellValue(row, value, cell);
cell.setSortCode(this._calculateCellSortCode(cell));
}
}
diff --git a/eclipse-scout-core/test/table/editor/CellEditorSpec.js b/eclipse-scout-core/test/table/editor/CellEditorSpec.js
index 194b52f..318d8d6 100644
--- a/eclipse-scout-core/test/table/editor/CellEditorSpec.js
+++ b/eclipse-scout-core/test/table/editor/CellEditorSpec.js
@@ -8,7 +8,7 @@
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
*/
-import {Cell, keys, scout, StaticLookupCall, Status, Widget} from '../../../src/index';
+import {Cell, keys, scout, StaticLookupCall, Status, TableRow, Widget} from '../../../src/index';
import {FormSpecHelper, TableSpecHelper} from '../../../src/testing/index';
describe('CellEditor', () => {
@@ -535,6 +535,25 @@
});
});
});
+
+ it('triggers update row event containing row with correct state', () => {
+ table.columns[0].setEditable(true);
+ table.markRowsAsNonChanged();
+ table.prepareCellEdit(table.columns[0], table.rows[0], true);
+ jasmine.clock().tick(300);
+ table.cellEditorPopup.cell.field.setValue('key1');
+ jasmine.clock().tick(300);
+ let updateRowCount = 0;
+ table.on('rowsUpdated', event => {
+ expect(event.rows[0].cells[0].value).toBe('key1');
+ expect(event.rows[0].cells[0].text).toBe('Key 1');
+ expect(event.rows[0].status).toBe(TableRow.Status.UPDATED);
+ updateRowCount++;
+ });
+ table.completeCellEdit();
+ jasmine.clock().tick(300);
+ expect(updateRowCount).toBe(1);
+ });
});
describe('cancelCellEdit', () => {