CollectionView

The CollectionView class is the main data management class used with Wijmo controls.

This creates a CollectionView object based on an array with 500 items.

The CollectionView is configured to show pages with 10 items each. The collection is shown in an HTML table that you can filter, sort, and group using the controls at the top of each column.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import * as wijmo from '@grapecity/wijmo'; import * as input from '@grapecity/wijmo.input'; import { getData } from './data'; import { TableView } from './table-view'; import { CollectionViewPager } from './collection-view-pager'; import { CollectionViewNavigator } from './collection-view-navigator'; import { ItemEditor } from './item-editor'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // // create a CollectionView let view = new wijmo.CollectionView(getData(500), { pageSize: 10, newItemCreator: () => { let newItem = getData(1)[0]; newItem.id = -1; return newItem; } }); // new TableView('#tableView', view, { amount: 'n2' }); new CollectionViewNavigator("#navigator", view); new CollectionViewPager("#pager", view); new ItemEditor('#editor', view); // let menu = new input.Menu("#pageSizeMenu", { itemsSource: [ { value: 0, text: 'No Paging' }, { value: 10, text: '10' }, { value: 15, text: '15' }, { value: 30, text: '30' }, { value: 50, text: '50' } ], displayMemberPath: 'text', selectedValuePath: 'value', selectedValue: view.pageSize, selectedIndexChanged: (sender) => { if (sender.selectedIndex >= 0) { updateMenuHeader(sender); view.pageSize = sender.selectedValue; } } }); updateMenuHeader(menu); // function updateMenuHeader(menu) { if (menu.selectedIndex >= 0) { menu.header = `Page Size: <b>${menu.selectedItem.text}</b>`; } } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity CollectionView Overview</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 id="menu"></div> <div class="row"> <div class="col-md-6"> <h4>Current Item</h4> <div id="editor"></div> </div> <div class="col-md-6"> <h4>Navigation</h4> <dl> <dt>items</dt> <dd> <div id="navigator"></div> </dd> <dt>pages</dt> <dd> <div id="pager"></div> </dd> </dl> <div id="pageSizeMenu"></div> </div> </div> <div id="tableView"></div> </div> </body> </html>
// export function getData(count) { let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'], colors = ['Black', 'White', 'Red', 'Green', 'Blue'], data = []; // // add count items for (let i = 0; i < count; i++) { // constants used to create data items let countryId = Math.floor(Math.random() * countries.length), colorId = Math.floor(Math.random() * colors.length); // // create the item let item = { id: i, country: countries[countryId], color: colors[colorId], amount: Math.random() * 10000 - 5000 }; // // add the item to the list data.push(item); } // return data; }
.table { margin-bottom: 0px !important; }
import * as wijmo from '@grapecity/wijmo'; export class CollectionViewNavigatorBase extends wijmo.Control { // constructor(element, view) { wijmo.assert(!!view, 'view must not be null.'); // super(element); // this.applyTemplate('wj-control wj-content wj-pager', this.getTemplate(), { _first: 'first', _prev: 'prev', _next: 'next', _last: 'last', _input: 'input' }); // this._first.addEventListener('click', () => this._onFirstClick()); this._prev.addEventListener('click', () => this._onPrevClick()); this._next.addEventListener('click', () => this._onNextClick()); this._last.addEventListener('click', () => this._onLastClick()); // this._view = view; this._view.collectionChanged.addHandler(() => this.invalidate()); this.invalidate(); } // get view() { return this._view; } } CollectionViewNavigatorBase.controlTemplate = `<div class="wj-input-group"> <span class="wj-input-group-btn" > <button class="wj-btn wj-btn-default" type="button" wj-part="first"> <span class="wj-glyph-left" style="margin-right: -4px;"></span> <span class="wj-glyph-left"></span> </button> </span> <span class="wj-input-group-btn" > <button class="wj-btn wj-btn-default" type="button" wj-part="prev"> <span class="wj-glyph-left"></span> </button> </span> <input type="text" class="wj-form-control" wj-part="input" disabled /> <span class="wj-input-group-btn" > <button class="wj-btn wj-btn-default" type="button" wj-part="next"> <span class="wj-glyph-right"></span> </button> </span> <span class="wj-input-group-btn" > <button class="wj-btn wj-btn-default" type="button" wj-part="last"> <span class="wj-glyph-right"></span> <span class="wj-glyph-right" style="margin-left: -4px;"></span> </button> </span> </div>`;
import { CollectionViewNavigatorBase } from './collection-view-navigator-base'; // export class CollectionViewNavigator extends CollectionViewNavigatorBase { constructor(element, view) { super(element, view); this.view.currentChanged.addHandler(() => this.invalidate()); } // refresh() { super.refresh(); this._first.disabled = this._prev.disabled = this.view.currentPosition <= 0; this._next.disabled = this._last.disabled = this.view.currentPosition >= this.view.itemCount - 1; this._input.value = `${this.view.currentPosition + 1} / ${this.view.itemCount}`; } // _onFirstClick() { this.view.moveCurrentToFirst(); } // _onPrevClick() { this.view.moveCurrentToPrevious(); } // _onNextClick() { this.view.moveCurrentToNext(); } // _onLastClick() { this.view.moveCurrentToLast(); } }
import { CollectionViewNavigatorBase } from './collection-view-navigator-base'; // export class CollectionViewPager extends CollectionViewNavigatorBase { constructor(element, view) { super(element, view); this.view.pageChanged.addHandler(() => this.invalidate()); } // refresh() { super.refresh(); this._first.disabled = this._prev.disabled = this.view.pageIndex <= 0; this._next.disabled = this._last.disabled = this.view.pageIndex >= this.view.pageCount - 1; this._input.value = `${this.view.pageIndex + 1} / ${this.view.pageCount}`; } // _onFirstClick() { this.view.moveToFirstPage(); } // _onPrevClick() { this.view.moveToPreviousPage(); } // _onNextClick() { this.view.moveToNextPage(); } // _onLastClick() { this.view.moveToLastPage(); } }
import * as wijmo from '@grapecity/wijmo'; // export class ItemEditor extends wijmo.Control { // constructor(element, view) { wijmo.assert(!!view, 'view must not be null.'); // super(element); // this.applyTemplate('', this.getTemplate(), { _tbId: 'id', _tbCountry: 'country', _tbColor: 'color', _tbAmount: 'amount', _btnEdit: 'edit', _btnAdd: 'add', _btnDelete: 'delete', _btnCommit: 'commit', _btnCancel: 'cancel' }); // this._btnEdit.addEventListener('click', () => this._edit()); this._btnAdd.addEventListener('click', () => this._add()); this._btnDelete.addEventListener('click', () => this._remove()); this._btnCommit.addEventListener('click', () => this._commit()); this._btnCancel.addEventListener('click', () => this._cancel()); // this._view = view; this._view.currentChanged.addHandler(() => this.invalidate()); // this.invalidate(); } refresh() { super.refresh(); // let cur = this._view.currentItem, edit = this._isEditing(); // this._tbId.disabled = !edit; this._tbCountry.disabled = !edit; this._tbColor.disabled = !edit; this._tbAmount.disabled = !edit; // this._tbId.value = cur ? cur.id.toString() : ''; this._tbCountry.value = cur ? cur.country.toString() : ''; this._tbColor.value = cur ? cur.color.toString() : ''; this._tbAmount.value = cur ? cur.amount.toString() : ''; // let display = edit ? 'none' : ''; this._btnEdit.style.display = display; this._btnAdd.style.display = display; this._btnDelete.style.display = display; // display = edit ? '' : 'none'; this._btnCommit.style.display = display; this._btnCancel.style.display = display; } // _isEditing() { return this._view.isEditingItem || this._view.isAddingNew; } // _edit() { this._view.editItem(this._view.currentItem); this.invalidate(); } // _add() { this._view.addNew(); } // _remove() { this._view.remove(this._view.currentItem); } // _commit() { let cur = this._view.currentItem; // cur.id = this._tbId.value; cur.country = this._tbCountry.value; cur.color = this._tbColor.value; cur.amount = this._tbAmount.value; // this._view.commitEdit(); this._view.commitNew(); this.invalidate(); } // _cancel() { this._view.cancelEdit(); this._view.cancelNew(); this.invalidate(); } } ItemEditor.controlTemplate = `<dl class="dl-horizontal"> <dt>ID</dt> <dd> <input type="text" class="form-control" wj-part="id" /> </dd> <dt>Country</dt> <dd> <input type="text" class="form-control" wj-part="country" /> </dd> <dt>Color</dt> <dd> <input type="text" class="form-control" wj-part="color" /> </dd> <dt>Amount</dt> <dd> <input type="number" class="form-control" wj-part="amount" /> </dd> <dt></dt> <dd> <div class="btn-group data-btn-group"> <button class="btn btn-default btn-sm" wj-part="edit">Edit</button> <button class="btn btn-default btn-sm" wj-part="add">Add</button> <button class="btn btn-default btn-sm" wj-part="delete">Delete</button> <button class="btn btn-default btn-sm" wj-part="commit">Commit</button> <button class="btn btn-default btn-sm" wj-part="cancel">Cancel</button> </div> </dd> </dl>`;
import * as wijmo from '@grapecity/wijmo'; // export class TableView extends wijmo.Control { // constructor(selector, view, format) { super(selector); // this.applyTemplate('table-responsive', this.getTemplate(), { _table: 'table' }); this._format = format || {}; // this._view = view; this._view.collectionChanged.addHandler(() => this.invalidate()); this._view.currentChanged.addHandler(() => this.invalidate()); // this.invalidate(); } // refresh() { this._table.innerHTML = ''; // // create header if (this._view.itemCount > 0) { let item = this._view.items[0], head = this._table.createTHead(), row = head.insertRow(); // row.className = 'active'; Object.keys(item).forEach(key => { let cell = document.createElement('th'); cell.className = 'text-center'; // // header text let txt = document.createTextNode(wijmo.toHeaderCase(key) + '\u00A0'); // + &nbsp; cell.appendChild(txt); // // sort button let btn = document.createElement('button'); btn.className = 'btn btn-default'; btn.textContent = this._getSort(key); btn.addEventListener('click', () => this._toggleSort(key)); cell.appendChild(btn); // row.appendChild(cell); }); } // // create body let body = this._table.createTBody(); this._view.items.forEach(item => { let row = body.insertRow(); // if (item == this._view.currentItem) { row.className = 'success'; } // row.addEventListener('click', () => this._moveCurrentTo(row, item)); // Object.keys(item).forEach(key => { let cell = row.insertCell(), fmt = this._format[key], val = item[key]; // cell.textContent = fmt ? wijmo.format(`{val:${fmt}}`, { val: val }) : val; cell.className = 'text-center'; }); }); } // _moveCurrentTo(row, item) { if (!this._isEditingView && !this._isGroupRow(item)) { this._view.moveCurrentTo(item); } } // get _isEditingView() { return this._view.isEditingItem || this._view.isAddingNew; } // _isGroupRow(item) { return item instanceof wijmo.CollectionViewGroup; } // _getSort(field) { let sd = this._view.sortDescriptions; // if (sd.length > 0 && sd[0].property === field) { return sd[0].ascending ? '▲' : '▼'; } // return '◇'; } // _toggleSort(field) { let sd = this._view.sortDescriptions, ascending = true; // if (sd.length > 0 && sd[0].property === field) { ascending = !sd[0].ascending; } // // remove any old sort descriptors and add the new one sd.splice(0, sd.length, new wijmo.SortDescription(field, ascending)); } } TableView.controlTemplate = '<table class="table table-condensed table-bordered" wj-part="table"></table>';
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'jszip': 'npm:jszip/dist/jszip.js', '@grapecity/wijmo': 'npm:@grapecity/wijmo/index.js', '@grapecity/wijmo.input': 'npm:@grapecity/wijmo.input/index.js', '@grapecity/wijmo.styles': 'npm:@grapecity/wijmo.styles', '@grapecity/wijmo.cultures': 'npm:@grapecity/wijmo.cultures', '@grapecity/wijmo.chart': 'npm:@grapecity/wijmo.chart/index.js', '@grapecity/wijmo.chart.analytics': 'npm:@grapecity/wijmo.chart.analytics/index.js', '@grapecity/wijmo.chart.animation': 'npm:@grapecity/wijmo.chart.animation/index.js', '@grapecity/wijmo.chart.annotation': 'npm:@grapecity/wijmo.chart.annotation/index.js', '@grapecity/wijmo.chart.finance': 'npm:@grapecity/wijmo.chart.finance/index.js', '@grapecity/wijmo.chart.finance.analytics': 'npm:@grapecity/wijmo.chart.finance.analytics/index.js', '@grapecity/wijmo.chart.hierarchical': 'npm:@grapecity/wijmo.chart.hierarchical/index.js', '@grapecity/wijmo.chart.interaction': 'npm:@grapecity/wijmo.chart.interaction/index.js', '@grapecity/wijmo.chart.radar': 'npm:@grapecity/wijmo.chart.radar/index.js', '@grapecity/wijmo.chart.render': 'npm:@grapecity/wijmo.chart.render/index.js', '@grapecity/wijmo.chart.webgl': 'npm:@grapecity/wijmo.chart.webgl/index.js', '@grapecity/wijmo.gauge': 'npm:@grapecity/wijmo.gauge/index.js', '@grapecity/wijmo.grid': 'npm:@grapecity/wijmo.grid/index.js', '@grapecity/wijmo.grid.detail': 'npm:@grapecity/wijmo.grid.detail/index.js', '@grapecity/wijmo.grid.filter': 'npm:@grapecity/wijmo.grid.filter/index.js', '@grapecity/wijmo.grid.search': 'npm:@grapecity/wijmo.grid.search/index.js', '@grapecity/wijmo.grid.grouppanel': 'npm:@grapecity/wijmo.grid.grouppanel/index.js', '@grapecity/wijmo.grid.multirow': 'npm:@grapecity/wijmo.grid.multirow/index.js', '@grapecity/wijmo.grid.transposed': 'npm:@grapecity/wijmo.grid.transposed/index.js', '@grapecity/wijmo.grid.transposedmultirow': 'npm:@grapecity/wijmo.grid.transposedmultirow/index.js', '@grapecity/wijmo.grid.pdf': 'npm:@grapecity/wijmo.grid.pdf/index.js', '@grapecity/wijmo.grid.sheet': 'npm:@grapecity/wijmo.grid.sheet/index.js', '@grapecity/wijmo.grid.xlsx': 'npm:@grapecity/wijmo.grid.xlsx/index.js', '@grapecity/wijmo.grid.selector': 'npm:@grapecity/wijmo.grid.selector/index.js', '@grapecity/wijmo.grid.cellmaker': 'npm:@grapecity/wijmo.grid.cellmaker/index.js', '@grapecity/wijmo.nav': 'npm:@grapecity/wijmo.nav/index.js', '@grapecity/wijmo.odata': 'npm:@grapecity/wijmo.odata/index.js', '@grapecity/wijmo.olap': 'npm:@grapecity/wijmo.olap/index.js', '@grapecity/wijmo.pdf': 'npm:@grapecity/wijmo.pdf/index.js', '@grapecity/wijmo.pdf.security': 'npm:@grapecity/wijmo.pdf.security/index.js', '@grapecity/wijmo.viewer': 'npm:@grapecity/wijmo.viewer/index.js', '@grapecity/wijmo.xlsx': 'npm:@grapecity/wijmo.xlsx/index.js', '@grapecity/wijmo.undo': 'npm:@grapecity/wijmo.undo/index.js', '@grapecity/wijmo.interop.grid': 'npm:@grapecity/wijmo.interop.grid/index.js', '@grapecity/wijmo.touch': 'npm:@grapecity/wijmo.touch/index.js', '@grapecity/wijmo.cloud': 'npm:@grapecity/wijmo.cloud/index.js', '@grapecity/wijmo.barcode': 'npm:@grapecity/wijmo.barcode/index.js', '@grapecity/wijmo.barcode.common': 'npm:@grapecity/wijmo.barcode.common/index.js', '@grapecity/wijmo.barcode.composite': 'npm:@grapecity/wijmo.barcode.composite/index.js', '@grapecity/wijmo.barcode.specialized': 'npm:@grapecity/wijmo.barcode.specialized/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);