CollectionView

CollectionViewクラスは、Wijmoコントロールで使用される主なデータ管理クラスです。このサンプルはICollectionViewがどのように機能するかを示します。500個の項目を持つ配列に基づいてCollectionViewオブジェクトを作成します。CollectionViewは、デフォルトでそれぞれ10項目のページを表示するように設定されています。コレクションはHTMLテーブルに表示され、各列の上部にあるコントロールを使用してフィルター、ソート、およびグループ化できます。

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: 'ページングなし' }, { 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 = `ページサイズ: <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>現在の項目</h4> <div id="editor"></div> </div> <div class="col-md-6"> <h4>ナビゲーション</h4> <dl> <dt>項目</dt> <dd> <div id="navigator"></div> </dd> <dt>ページ</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 = ['アメリカ', 'ドイツ', 'イギリス', '日本', 'イタリア', 'ギリシャ'], colors = ['黒', '白', '赤', '緑', '青'], 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.floor(Math.random() * 10000) }; // // 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>国</dt> <dd> <input type="text" class="form-control" wj-part="country" /> </dd> <dt>色</dt> <dd> <input type="text" class="form-control" wj-part="color" /> </dd> <dt>金額</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">編集</button> <button class="btn btn-default btn-sm" wj-part="add">追加</button> <button class="btn btn-default btn-sm" wj-part="delete">削除</button> <button class="btn btn-default btn-sm" wj-part="commit">確定</button> <button class="btn btn-default btn-sm" wj-part="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({ id: 'ID', country: '国', color: '色', amount: '金額' }[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.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.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', '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);