Tracking Changings in CollectionView

The CollectionView can help by keeping track of modified items when the trackChanges property is set to true. When enabled, the CollectionView updates the itemsAdded, itemsRemoved, and itemsEdited collections as content is edited. This sample displays these collections in separate grids to show how the changes are tracked.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wijmo from '@grapecity/wijmo'; import * as grid from '@grapecity/wijmo.grid'; import { getData } from './data'; document.readyState === 'complete' ? init() : window.onload = init; function init() { // create a CollectionView with change tracking let view = new wijmo.CollectionView(getData(), { sortDescriptions: ['country'], trackChanges: true }); // create grid for editing let theGrid = new grid.FlexGrid('#theGrid', { itemsSource: view, allowAddNew: true, allowDelete: true }); // create grids to show changes let edited = new grid.FlexGrid('#edited', { itemsSource: view.itemsEdited, isReadOnly: true }); let added = new grid.FlexGrid('#added', { itemsSource: view.itemsAdded, isReadOnly: true }); let removed = new grid.FlexGrid('#removed', { itemsSource: view.itemsRemoved, isReadOnly: true }); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity CollectionView Change Tracking</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-xs-6"> <div id="theGrid"></div> </div> <div class="col-xs-6"> <h4>Edited Items:</h4> <div id="edited" class="changed edited"></div> <h4>Added Items:</h4> <div id="added" class="changed added"></div> <h4>Removed Items:</h4> <div id="removed" class="changed removed"></div> </div> </div> </div> </body> </html> export function getData() { let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy'], data = []; for (let i = 0; i < countries.length; i++) { data.push({ country: countries[i], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; } .wj-flexgrid:not(.changed) { height: 300px; } .changed { font-size: 90%; background-color: #f0f0f0 } .edited { color: orange } .added { color: green } .removed { color: red } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import * as wijmo from '@grapecity/wijmo'; // import { Component, Inject, enableProdMode, NgModule } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { WjGridModule } from '@grapecity/wijmo.angular2.grid'; import { DataService } from './app.data'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { view: wijmo.CollectionView; // constructor(@Inject(DataService) private dataService: DataService) { this.view = new wijmo.CollectionView(dataService.getData(), { sortDescriptions: ['country'], trackChanges: true }); } } // @NgModule({ imports: [WjGridModule, BrowserModule], declarations: [AppComponent], providers: [DataService], bootstrap: [AppComponent] }) export class AppModule { } // enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity CollectionView Change Tracking</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Polyfills --> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.min.js"></script> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html> <div class="container-fluid"> <div class="row"> <div class="col-xs-6"> <wj-flex-grid [itemsSource]="view" [allowAddNew]="true" [allowDelete]="true"> </wj-flex-grid> </div> <div class="col-xs-6"> <h4>Edited Items:</h4> <wj-flex-grid class="changed edited" [itemsSource]="view.itemsEdited" [isReadOnly]="true"> </wj-flex-grid> <h4>Added Items:</h4> <wj-flex-grid class="changed added" [itemsSource]="view.itemsAdded" [isReadOnly]="true"> </wj-flex-grid> <h4>Removed Items:</h4> <wj-flex-grid class="changed removed" [itemsSource]="view.itemsRemoved" [isReadOnly]="true"> </wj-flex-grid> </div> </div> </div> import { Injectable } from '@angular/core'; // @Injectable() export class DataService { getData() { let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy'], data = []; for (let i = 0; i < countries.length; i++) { data.push({ country: countries[i], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; } } .wj-flexgrid:not(.changed) { height: 300px; } .changed { font-size: 90%; background-color: #f0f0f0 } .edited { color: orange } .added { color: green } .removed { color: red } <template> <div class="container-fluid"> <div class="row"> <div class="col-xs-6"> <wj-flex-grid :itemsSource="view" :allowAddNew="true" :allowDelete="true"> </wj-flex-grid> </div> <div class="col-xs-6"> <h4>Edited Items:</h4> <wj-flex-grid class="changed edited" :itemsSource="view.itemsEdited" :isReadOnly="true"> </wj-flex-grid> <h4>Added Items:</h4> <wj-flex-grid class="changed added" :itemsSource="view.itemsAdded" :isReadOnly="true"> </wj-flex-grid> <h4>Removed Items:</h4> <wj-flex-grid class="changed removed" :itemsSource="view.itemsRemoved" :isReadOnly="true"> </wj-flex-grid> </div> </div> </div> </template> <script> import "bootstrap.css"; import "@grapecity/wijmo.styles/wijmo.css"; import Vue from "vue"; import "@grapecity/wijmo.vue2.grid"; import * as wijmo from "@grapecity/wijmo"; import { getData } from "./data"; let App = Vue.extend({ name: "app", data: function() { return { view: new wijmo.CollectionView(getData(), { sortDescriptions: ["country"], trackChanges: true }) }; } }); new Vue({ render: h => h(App) }).$mount("#app"); </script> <style> .wj-flexgrid:not(.changed) { height: 300px; } .wj-flexgrid.changed { font-size: 90%; background-color: #f0f0f0 } .wj-flexgrid.edited { color: orange } .wj-flexgrid.added { color: green } .wj-flexgrid.removed { color: red } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity CollectionView Change Tracking</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); </script> </head> <body> <div id="app"> </div> </body> </html> export function getData() { let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy'], data = []; for (let i = 0; i < countries.length; i++) { data.push({ country: countries[i], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './app.css'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { CollectionView } from '@grapecity/wijmo'; import { FlexGrid } from '@grapecity/wijmo.react.grid'; import { getData } from './data'; class App extends React.Component { constructor(props) { super(props); this.state = { view: new CollectionView(getData(), { sortDescriptions: ["country"], trackChanges: true }) }; } render() { return <div className="container-fluid"> <div className="row"> <div className="col-xs-6"> <FlexGrid itemsSource={this.state.view} allowAddNew={true} allowDelete={true}> </FlexGrid> </div> <div className="col-xs-6"> <h4>Edited Items:</h4> <FlexGrid className="changed edited" itemsSource={this.state.view.itemsEdited} isReadOnly={true}> </FlexGrid> <h4>Added Items:</h4> <FlexGrid className="changed added" itemsSource={this.state.view.itemsAdded} isReadOnly={true}> </FlexGrid> <h4>Removed Items:</h4> <FlexGrid className="changed removed" itemsSource={this.state.view.itemsRemoved} isReadOnly={true}> </FlexGrid> </div> </div> </div>; } } ReactDOM.render(<App />, document.getElementById('app')); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>AutoComplete</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div id="app"></div> </body> </html> .wj-flexgrid:not(.changed) { height: 300px; } .changed { font-size: 90%; background-color: #f0f0f0 } .edited { color: orange } .added { color: green } .removed { color: red } export function getData() { let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy'], data = []; for (let i = 0; i < countries.length; i++) { data.push({ country: countries[i], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; }