Skip to content

Commit 36b803a

Browse files
DataGrid: fix validation data object with repaintChangesOnly (T1323690) (#32901)
1 parent de72b05 commit 36b803a

2 files changed

Lines changed: 94 additions & 1 deletion

File tree

packages/devextreme/js/__internal/grids/grid_core/validating/__tests__/validating.integration.test.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
afterEach, beforeEach, describe, expect, it, jest,
33
} from '@jest/globals';
4+
import type { CustomRule } from '@js/common';
45
import {
56
afterTest,
67
beforeTest,
@@ -71,6 +72,96 @@ describe('DataGrid Cell Editing', () => {
7172
expect(instance.cellValue(1, 'name')).toBe('Job 2');
7273
expect(component.getDataCell(1, 0).isValidCell).toBe(true);
7374
});
75+
76+
// T1323690
77+
it('should pass real row data to validationCallback after canceling changes (T1323690)', async () => {
78+
const validationCallback = jest.fn<NonNullable<CustomRule['validationCallback']>>(
79+
(e) => !e.value?.toString().includes('X'),
80+
);
81+
const data = [
82+
{ id: 1, name: 'Item 1', description: 'Desc A' },
83+
{ id: 2, name: 'Item 2', description: 'Desc B' },
84+
];
85+
86+
const { component } = await createDataGrid({
87+
dataSource: data,
88+
keyExpr: 'id',
89+
repaintChangesOnly: true,
90+
editing: {
91+
mode: 'cell',
92+
allowUpdating: true,
93+
},
94+
columns: [
95+
{
96+
dataField: 'name',
97+
showEditorAlways: true,
98+
validationRules: [
99+
{
100+
type: 'custom',
101+
validationCallback,
102+
},
103+
],
104+
},
105+
'description',
106+
],
107+
});
108+
109+
const firstEditor = component.getDataCell(0, 0).getEditor(TextBoxModel);
110+
firstEditor.setValue('Item 1X');
111+
jest.runAllTimers();
112+
113+
expect(validationCallback).toHaveBeenCalledTimes(1);
114+
expect(component.getDataCell(0, 0).isValidCell).toBe(false);
115+
116+
component.getRevertButton().click();
117+
jest.runAllTimers();
118+
119+
const secondCell = component.getDataCell(1, 0);
120+
secondCell.getElement()?.click();
121+
jest.runAllTimers();
122+
123+
expect(validationCallback).toHaveBeenCalled();
124+
const lastCallData = validationCallback.mock.lastCall?.[0].data;
125+
expect(lastCallData).toMatchObject(data[1]);
126+
});
127+
128+
it('should pass edited data to validationCallback during active editing (T1323690)', async () => {
129+
const validationCallback = jest.fn<NonNullable<CustomRule['validationCallback']>>(() => true);
130+
const data = [
131+
{ id: 1, name: 'Item 1', description: 'Desc A' },
132+
];
133+
134+
const { component } = await createDataGrid({
135+
dataSource: data,
136+
keyExpr: 'id',
137+
repaintChangesOnly: true,
138+
editing: {
139+
mode: 'cell',
140+
allowUpdating: true,
141+
},
142+
columns: [
143+
{
144+
dataField: 'name',
145+
showEditorAlways: true,
146+
validationRules: [
147+
{
148+
type: 'custom',
149+
validationCallback,
150+
},
151+
],
152+
},
153+
'description',
154+
],
155+
});
156+
157+
const editor = component.getDataCell(0, 0).getEditor(TextBoxModel);
158+
editor.setValue('Changed');
159+
jest.runAllTimers();
160+
161+
expect(validationCallback).toHaveBeenCalled();
162+
const lastCallData = validationCallback.mock.lastCall?.[0].data;
163+
expect(lastCallData).toMatchObject({ id: 1, name: 'Changed', description: 'Desc A' });
164+
});
74165
});
75166

76167
// T1296376

packages/devextreme/js/__internal/grids/grid_core/validating/m_validating.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,9 @@ export class ValidatingController extends modules.Controller {
503503
const change = editingController.getChangeByKey(key);
504504
const oldData = editingController._getOldData(key);
505505
return {
506-
data: createObjectWithChanges(oldData, change?.data),
506+
data: change
507+
? createObjectWithChanges(oldData, change.data)
508+
: { ...oldData ?? parameters.data },
507509
column,
508510
};
509511
},

0 commit comments

Comments
 (0)