The Problem
The DataGrid and TreeList components do not provide an API to perform the following tasks:
- Get or set updated/inserted/deleted rows
- Save all rows in one request in batch edit mode
- Cancel changes made to an individual row in batch edit mode
- Be notified when editing is finished
The Proposed Solution
We plan to introduce the following API:
Options
editing.editRowKey: any // key for the edited row
editing.editColumnName: string // name of the edited column
editing.changes: object[] // pending row changes
changes is an array of objects with the following fields:
type - "insert", "update", or "remove"
data - the row's updated data fields
key - the row's key
Events
onSaving: function // A callback function that is executed before edited data is saved
onSaved: function // A callback function that is executed after edited data is saved
onEditCanceling: function // A callback function that is called before editing is canceled
onEditCanceled: function // A callback function that is called after editing is canceled
Utils
DevExpress.data.applyChanges(data, changes, { keyExpr, immutable }) // A method that applies changes to data
data - the current dataset
changes - changes to be applied to the dataset
keyExpr - specifies the key property
immutable - if true, applyChanges returns a new array instead of modifying data
The applyChanges method makes it easier to update the grid's data source. If this method does not meet your requirements, you can use your own update implementation instead.
Controlled Mode
You can use the newly introduced API to implement your own data-saving logic in the onSaving handler. To handle data modification manually, set the cancel parameter to true to disable the default saving implementation as follows:
Angular
// app.component.html
<dx-data-grid
keyExpr="ID"
[dataSource]="data"
(onSaving)="onSaving($event)"
>
<dxo-editing
mode="batch"
[allowUpdating]="true"
[(changes)]="changes"
[(editRowKey)]="editRowKey"
[(editColumnName)]="editColumnName"
></dxo-editing>
</dx-data-grid>
. . .
// app.component.ts
export class AppComponent {
data: any[];
editRowKey: any;
editColumnName: string;
changes: Array<any>;
constructor(service: Service) {
this.data = service.getData();
this.editRowKey = null;
this.editColumnName = null;
this.changes = [];
}
onSaving(e) {
e.cancel = true; // cancel automatic update of the data array
// await fetch(. . .); // save data to your remote server if needed
// apply changes to your local data
// you can use our applyChanges method or implement your own data modification logic
applyChanges(this.data, this.changes, {
keyExpr: 'ID',
immutable: false
});
this.editRowKey = null;
this.editColumnName = null;
this.changes = [];
}
}
React
const [editColumnName, setEditColumnName] = useState(null);
const [editRowKey, setEditRowKey] = useState(null);
const [changes, setChanges] = useState(null);
const [data, setData] = useState([]);
. . .
<DataGrid
keyExpr="ID"
dataSource={data}
onSaving={onSaving}
>
<Editing
mode="batch"
allowUpdating={true}
changes={changes}
onChangesChange={setChanges}
editRowKey={editRowKey}
onEditRowKeyChange={setEditRowKey}
editColumnName={editColumnName}
onEditColumnNameChange={setEditColumnName}
/>
</DataGrid>
. . .
onSaving(e) {
e.cancel = true; // cancel automatic update of the data array
// await fetch(. . .); // save data to your remote server if needed
// apply changes to your local data
// you can use our applyChanges method or implement your own data modification logic
const newData = applyChanges(data, changes, {
keyExpr: 'ID',
immutable: true
});
setData(newData);
setChanges([]);
setEditColumnName(null);
setEditRowKey(null);
});
}
Vue
<template>
<div>
<DxDataGrid
key-expr="ID"
:data-source="data"
@saving="onSaving"
>
<DxEditing
mode="batch"
:allow-updating="true"
:changes.sync="changes"
:edit-row-key.sync="editRowKey"
:edit-column-name.sync="editColumnName"
/>
</DxDataGrid>
</div>
</template>
. . .
export default {
data() {
return {
data: [. . .],
editRowKey: null,
editColumnName: null,
changes: []
};
},
methods: {
onSaving(e) {
e.cancel = true; // cancel automatic update of the data array
// await fetch(. . .); // save data to your remote server if needed
// apply changes to your local data
// you can use our applyChanges method or implement your own data modification logic
applyChanges(this.data, this.changes, {
keyExpr: 'ID',
immutable: false
});
this.editRowKey = null;
this.editColumnName = null;
this.changes = [];
}
},
};
jQuery
$('#gridContainer').dxDataGrid({
dataSource: data,
editing: {
mode: 'batch',
allowUpdating: true,
},
onSaving: function(e) {
e.cancel = true; // cancel automatic update of the data array
// await fetch(. . .); // save data to your remote server if needed
// apply changes to your local data
// you can use our applyChanges method or implement your own data modification logic
DevExpress.data.applyChanges(data, e.changes, {
keyExpr: 'ID',
immutable: false
});
e.component.option({
dataSource: data,
editing: {
editRowKey: null,
editColumnName: null,
changes: []
}
});
}
});
Send All Changes in a Single Request
In batch edit mode, the DataGrid sends a separate request for each object in the changes array. To optimize this operation and send all changes in one request, implement the onSaving event handler with the cancel parameter set to true. This cancels the DataGrid's default saving behavior and allows you to use your own implementation.
Angular
// app.component.html
<dx-data-grid
[dataSource]="store"
(onSaving)="onSaving($event)"
>
<dxo-editing
mode="batch"
[allowUpdating]="true"
[changes]="changes"
[editRowKey]="editRowKey"
></dxo-editing>
</dx-data-grid>
. . .
// app.component.ts
import * as AspNetData from "devextreme-aspnet-data-nojquery";
. . .
export class AppComponent {
store: any;
changes: any[];
editRowKey: any;
constructor(service: Service) {
this.store = AspNetData.createStore( . . . );
this.changes = [];
this.editRowKey = null;
}
onSaving(e) {
e.cancel = true; // prevent DataGrid from sending a separate request for each element in the changes array
const changes = e.changes;
// assign the promise returned from fetch to the promise field to display the load panel during remote saving
// if this promise is rejected, the DataGrid displays the error row
e.promise = fetch(. . .).then(() => {
this.editRowKey = null;
this.changes = [];
this.store.push(changes); // use store's Push API to apply changes locally
});
}
}
Refer to the first example to convert this code to React, Vue, or jQuery.
Handle Events Raised When Editing is Finished
Angular
// app.component.html
<dx-data-grid
[dataSource]="data"
(onSaved)="onSaved($event)"
(onEditCanceled)="onEditCanceled($event)"
>
<dxo-editing
mode="batch"
[allowUpdating]="true"
></dxo-editing>
</dx-data-grid>
. . .
// app.component.ts
export class AppComponent {
data: any[];
constructor(service: Service) {
this.data = service.getData();
}
onSaved(e) {
alert('data was saved');
}
onEditCanceled(e) {
alert('editing was canceled');
}
}
Refer to the first example to convert this code to React, Vue, or jQuery.
Try It
Live Sandboxes
We Need Your Feedback
Take a Quick Poll
Do you find DataGrid and TreeList editing API enhancements useful?
Get Notified of Updates
Subscribe to this thread - or to our Facebook and Twitter accounts - for updates on this topic.
The Problem
The DataGrid and TreeList components do not provide an API to perform the following tasks:
The Proposed Solution
We plan to introduce the following API:
Options
changesis an array of objects with the following fields:type- "insert", "update", or "remove"data- the row's updated data fieldskey- the row's keyEvents
Utils
data- the current datasetchanges- changes to be applied to the datasetkeyExpr- specifies the key propertyimmutable- iftrue,applyChangesreturns a new array instead of modifyingdataThe
applyChangesmethod makes it easier to update the grid's data source. If this method does not meet your requirements, you can use your own update implementation instead.Controlled Mode
You can use the newly introduced API to implement your own data-saving logic in the
onSavinghandler. To handle data modification manually, set thecancelparameter to true to disable the default saving implementation as follows:Angular
React
Vue
jQuery
Send All Changes in a Single Request
In batch edit mode, the DataGrid sends a separate request for each object in the
changesarray. To optimize this operation and send all changes in one request, implement theonSavingevent handler with thecancelparameter set to true. This cancels the DataGrid's default saving behavior and allows you to use your own implementation.Angular
Refer to the first example to convert this code to React, Vue, or jQuery.
Handle Events Raised When Editing is Finished
Angular
Refer to the first example to convert this code to React, Vue, or jQuery.
Try It
Live Sandboxes
We Need Your Feedback
Take a Quick Poll
Do you find DataGrid and TreeList editing API enhancements useful?
Get Notified of Updates
Subscribe to this thread - or to our Facebook and Twitter accounts - for updates on this topic.