Your search did not match any results.
Data Grid

CRUD Operations

Documentation

This demo shows how to implement remote CRUD operations in the CustomStore. You can view the server implementation under the DataGridWebApiController tab in the ASP.NET MVC version of this demo. The requests sent to the server are displayed under the DataGrid.

After a cell is edited, the DataGrid can behave differently depending on the selected refresh mode: reload data from the server (the refreshMode is full), reapply data processing operations (reshape), or merely rerender the changed cells (repaint).

Copy to CodeSandBox
Apply
Reset
<dx-data-grid id="grid" [dataSource]="dataSource" [repaintChangesOnly]="true" [showBorders]="true"> <dxo-scrolling mode="virtual"></dxo-scrolling> <dxo-editing mode="cell" [refreshMode]="refreshMode" [allowAdding]="true" [allowUpdating]="true" [allowDeleting]="true"> </dxo-editing> <dxi-column dataField="CustomerID" caption="Customer"> <dxo-lookup [dataSource]="customersData" valueExpr="Value" displayExpr="Text"></dxo-lookup> </dxi-column> <dxi-column dataField="OrderDate" dataType="date"></dxi-column> <dxi-column dataField="Freight"></dxi-column> <dxi-column dataField="ShipCountry"></dxi-column> <dxi-column dataField="ShipVia" caption="Shipping Company" dataType="number"> <dxo-lookup [dataSource]="shippersData" valueExpr="Value" displayExpr="Text"></dxo-lookup> </dxi-column> <dxo-summary> <dxi-total-item column="CustomerID" summaryType="count"> </dxi-total-item> <dxi-total-item column="Freight" summaryType="sum" valueFormat="#0.00"> </dxi-total-item> </dxo-summary> </dx-data-grid> <div class="options"> <div class="caption">Options</div> <div class="option"> <span>Refresh Mode:</span> <dx-select-box [(value)]="refreshMode" [items]="refreshModes"> </dx-select-box> </div> <div id="requests"> <div> <div class="caption">Network Requests</div> <dx-button id="clear" text="Clear" (onClick)="clearRequests()"> </dx-button> </div> <ul> <li *ngFor="let request of requests">{{request}}</li> </ul> </div> </div>
import { NgModule, Component, enableProdMode, ChangeDetectionStrategy } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { HttpClient, HttpClientModule, HttpHeaders, HttpParams } from '@angular/common/http'; import { DxDataGridModule, DxSelectBoxModule, DxButtonModule } from 'devextreme-angular'; import CustomStore from 'devextreme/data/custom_store'; import { formatDate } from 'devextreme/localization'; if(!/localhost/.test(document.location.host)) { enableProdMode(); } var URL = "https://js.devexpress.com/Demos/Mvc/api/DataGridWebApi"; @Component({ selector: 'demo-app', templateUrl: 'app/app.component.html', styleUrls: ['app/app.component.css'], preserveWhitespaces: true }) export class AppComponent { dataSource: any; customersData: any; shippersData: any; refreshModes: string[]; refreshMode: string; requests: string[] = []; constructor(private http: HttpClient) { this.refreshMode = "reshape"; this.refreshModes = ["full", "reshape", "repaint"]; this.dataSource = new CustomStore({ key: "OrderID", load: () => this.sendRequest(URL + "/Orders"), insert: (values) => this.sendRequest(URL + "/InsertOrder", "POST", { values: JSON.stringify(values) }), update: (key, values) => this.sendRequest(URL + "/UpdateOrder", "PUT", { key: key, values: JSON.stringify(values) }), remove: (key) => this.sendRequest(URL + "/DeleteOrder", "DELETE", { key: key }) }); this.customersData = { paginate: true, store: new CustomStore({ key: "Value", loadMode: "raw", load: () => this.sendRequest(URL + "/CustomersLookup") }) }; this.shippersData = new CustomStore({ key: "Value", loadMode: "raw", load: () => this.sendRequest(URL + "/ShippersLookup") }); } sendRequest(url: string, method: string = "GET", data: any = {}): any { this.logRequest(method, url, data); let httpParams = new HttpParams({ fromObject: data }); let httpOptions = { withCredentials: true, body: httpParams }; let result; switch(method) { case "GET": result = this.http.get(url, httpOptions); break; case "PUT": result = this.http.put(url, httpParams, httpOptions); break; case "POST": result = this.http.post(url, httpParams, httpOptions); break; case "DELETE": result = this.http.delete(url, httpOptions); break; } return result .toPromise() .then((data: any) => { return method === "GET" ? data.data : data; }) .catch(e => { throw e && e.error && e.error.Message; }); } logRequest(method: string, url: string, data: object): void { var args = Object.keys(data || {}).map(function(key) { return key + "=" + data[key]; }).join(" "); var time = formatDate(new Date(), "HH:mm:ss"); this.requests.unshift([time, method, url.slice(URL.length), args].join(" ")) } clearRequests() { this.requests = []; } } @NgModule({ imports: [ BrowserModule, DxDataGridModule, DxSelectBoxModule, DxButtonModule, HttpClientModule ], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { } platformBrowserDynamic().bootstrapModule(AppModule);
::ng-deep #grid { height: 440px; } ::ng-deep .options { padding: 20px; margin-top: 20px; background-color: rgba(191, 191, 191, 0.15); } ::ng-deep .caption { margin-bottom: 10px; font-weight: 500; font-size: 18px; } ::ng-deep .option { margin-bottom: 10px; } ::ng-deep .option > span { position: relative; top: 2px; margin-right: 10px; } ::ng-deep .option > .dx-widget { display: inline-block; vertical-align: middle; } ::ng-deep #requests .caption { float: left; padding-top: 7px; } ::ng-deep #requests > div { padding-bottom: 5px; } ::ng-deep #requests > div:after { content: ""; display: table; clear: both; } ::ng-deep #requests #clear { float: right; } ::ng-deep #requests ul { list-style: none; max-height: 100px; overflow: auto; margin: 0; } ::ng-deep #requests ul li { padding: 7px 0; border-bottom: 1px solid #dddddd; } ::ng-deep #requests ul li:last-child { border-bottom: none; }
// In real applications, you should not transpile code in the browser. You can see how to create your own application with Angular and DevExtreme here: // https://github.com/DevExpress/devextreme-angular/blob/master/README.md System.config({ transpiler: 'ts', typescriptOptions: { module: "commonjs", emitDecoratorMetadata: true, experimentalDecorators: true }, meta: { 'typescript': { "exports": "ts" }, 'devextreme-aspnet-data-nojquery': { "esModule": true } }, paths: { 'npm:': 'https://unpkg.com/' }, map: { 'ts': 'npm:plugin-typescript@7.0.6/lib/plugin.js', 'typescript': 'npm:typescript@2.2.2/lib/typescript.js', '@angular/core': 'npm:@angular/core@7.1.3/bundles/core.umd.js', '@angular/common': 'npm:@angular/common@7.1.3/bundles/common.umd.js', '@angular/compiler': 'npm:@angular/compiler@7.1.3/bundles/compiler.umd.js', '@angular/platform-browser': 'npm:@angular/platform-browser@7.1.3/bundles/platform-browser.umd.js', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic@7.1.3/bundles/platform-browser-dynamic.umd.js', '@angular/router': 'npm:@angular/router@7.1.3/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms@7.1.3/bundles/forms.umd.js', '@angular/common/http': 'npm:@angular/common@7.1.3/bundles/common-http.umd.js', 'tslib': 'npm:tslib/tslib.js', 'rxjs': 'npm:rxjs@6.3.3', 'rxjs/operators': 'npm:rxjs@6.3.3/operators', 'devextreme': 'npm:devextreme@19.1', 'jszip': 'npm:jszip@3.1.3/dist/jszip.min.js', 'quill': 'npm:quill@1.3.6/dist/quill.js', 'devexpress-diagram': 'npm:devexpress-diagram', 'devextreme-angular': 'npm:devextreme-angular@19.1' }, packages: { 'app': { main: './app.component.ts', defaultExtension: 'ts' }, 'devextreme': { defaultExtension: 'js' }, 'rxjs': { main: 'index.js', defaultExtension: 'js' }, 'rxjs/operators': { main: 'index.js', defaultExtension: 'js' }, 'devextreme-angular': { main: 'index.js', defaultExtension: 'js' } } });
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/19.1.3/css/dx.common.css" /> <link rel="dx-theme" data-theme="generic.light" href="https://cdn3.devexpress.com/jslib/19.1.3/css/dx.light.css" /> <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script> <script src="https://unpkg.com/zone.js@0.6.25/dist/zone.js"></script> <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script src="config.js"></script> <script> System.import('app').catch(console.error.bind(console)); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <demo-app>Loading...</demo-app> </div> </body> </html>