示例
概览
此视图显示FlexGrid控件的基本功能。它将网格绑定到数据源,并具有下面的菜单,允许您选择数据项的数量,选择模式和文化,以及是否使用数据映射和格式。请注意,即使有大量数据项,网格仍然保持快速流畅。 FlexGrid通过自动虚拟化行和列来实现此级别的性能。
您可以使用键盘和鼠标选择单元格和范围。当前选择会自动在屏幕上更新。使用下面的“选择”菜单尝试各种选择模式。请注意,ListBox模式允许您选择不连续的行。
您可以通过拖动鼠标来调整大小和移动列,并通过双击列标题的右边缘自动调整列的大小。如果在调整所选列的大小时按控制键,则会调整所有选定列的大小。
您可以通过单击列标题对列进行排序。单击列标题时按控制键以删除排序。
网格上方的过滤器和导航栏允许您过滤和浏览数据。两者都使用ICollectionView接口实现,就像在C#和.NET中一样。
请注意,与标准的AngularJS搜索过滤器不同,此过滤器支持多项搜索,因此如果您键入 us gad red,则网格会显示包含 所有 这些项的项目(国家/地区为“US”,产品是'Gadget',颜色是'红色')。
底部的按钮演示了列和行的isVisible属性,以及列宽和行高属性,如以及FlexGridscrollPosition属性。
import 'bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
import './styles.css';
import * as wjCore from '@grapecity/wijmo';
import * as wjInput from '@grapecity/wijmo.input';
import * as wjGrid from '@grapecity/wijmo.grid';
import { getData, getColors, getCountries, getProducts } from './data';
document.readyState === 'complete' ? init() : window.onload = init;
function init() {
// bind a grid to the data
let theGrid = new wjGrid.FlexGrid('#theGrid');
theGrid.select(new wjGrid.CellRange(0, 0));
theGrid.selectionChanged.addHandler((s, e) => {
document.querySelector('#cellRange').innerHTML = formatCellRange(e.range);
});
let toFilter;
document.querySelector('#filter').addEventListener('keyup', () => {
if (toFilter) {
clearTimeout(toFilter);
}
toFilter = setTimeout(function () {
toFilter = null;
if (theGrid) {
let cv = theGrid.collectionView;
if (cv) {
if (cv.filter != filterFunction) {
cv.filter = filterFunction;
}
else {
cv.refresh();
}
}
}
}, 500);
});
document.querySelector('#first').addEventListener('click', () => {
theGrid.collectionView.moveCurrentToFirst();
});
document.querySelector('#previous').addEventListener('click', () => {
theGrid.collectionView.moveCurrentToPrevious();
});
document.querySelector('#next').addEventListener('click', () => {
theGrid.collectionView.moveCurrentToNext();
});
document.querySelector('#last').addEventListener('click', () => {
theGrid.collectionView.moveCurrentToLast();
});
// create item count menu
let itemCountMenu = new wjInput.Menu('#itemCountMenu', {
// update header to show current selection
selectedIndexChanged: function (s, e) {
if (s.selectedIndex > -1) {
formatMenuHeader(s);
theGrid.itemsSource = getData(s.selectedValue, currentItemChanged.bind(this));
if (dataMapsMenu) {
updateDataMaps(dataMapsMenu.selectedValue);
}
if (formattingMenu) {
updateFormatting(formattingMenu.selectedValue);
}
currentItemChanged();
}
},
header: 'Items',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: '5', value: 5 },
{ header: '50', value: 50 },
{ header: '500', value: 500 },
{ header: '5,000', value: 5000 },
{ header: '50,000', value: 50000 },
{ header: '100,000', value: 100000 },
{ header: '500,000', value: 500000 },
{ header: '1,000,000', value: 1000000 }
]
});
// initialize value
itemCountMenu.selectedValue = 500;
// create allow add new menu
let allowAddNewMenu = new wjInput.Menu('#allowAddNewMenu', {
// update header to show current selection
selectedIndexChanged: function (s, e) {
if (s.selectedIndex > -1) {
formatMenuHeader(s);
theGrid.allowAddNew = s.selectedValue;
}
},
header: 'Allow Add',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: 'Yes', value: true },
{ header: 'No', value: false }
]
});
// initialize value
allowAddNewMenu.selectedValue = false;
// create selection mode menu
let selectionModeMenu = new wjInput.Menu('#selectionModeMenu', {
// update header to show current selection
selectedIndexChanged: function (s, e) {
if (s.selectedIndex > -1) {
formatMenuHeader(s);
theGrid.selectionMode = s.selectedValue;
}
},
header: 'Selection',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: 'None', value: wjGrid.SelectionMode.None },
{ header: 'Cell', value: wjGrid.SelectionMode.Cell },
{ header: 'CellRange', value: wjGrid.SelectionMode.CellRange },
{ header: 'Row', value: wjGrid.SelectionMode.Row },
{ header: 'RowRange', value: wjGrid.SelectionMode.RowRange },
{ header: 'ListBox', value: wjGrid.SelectionMode.ListBox }
]
});
// initialize value
selectionModeMenu.selectedValue = wjGrid.SelectionMode.CellRange;
theGrid.selection = new wjGrid.CellRange(0, 0);
// create header visibility menu
let headersVisibilityMenu = new wjInput.Menu('#headersVisibilityMenu', {
// update header to show current selection
selectedIndexChanged: function (s, e) {
if (s.selectedIndex > -1) {
formatMenuHeader(s);
theGrid.headersVisibility = s.selectedValue;
}
},
header: 'Headers Visibility',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: 'None', value: wjGrid.HeadersVisibility.None },
{ header: 'Column', value: wjGrid.HeadersVisibility.Column },
{ header: 'Row', value: wjGrid.HeadersVisibility.Row },
{ header: 'All', value: wjGrid.HeadersVisibility.All }
]
});
// initialize value
headersVisibilityMenu.selectedValue = wjGrid.HeadersVisibility.All;
// create show selected headers menu
let showSelectedHeadersMenu = new wjInput.Menu('#showSelectedHeadersMenu', {
// update header to show current selection
selectedIndexChanged: function (s, e) {
if (s.selectedIndex > -1) {
formatMenuHeader(s);
theGrid.showSelectedHeaders = s.selectedValue;
}
},
header: 'Show Selected Headers',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: 'None', value: wjGrid.HeadersVisibility.None },
{ header: 'Column', value: wjGrid.HeadersVisibility.Column },
{ header: 'Row', value: wjGrid.HeadersVisibility.Row },
{ header: 'All', value: wjGrid.HeadersVisibility.All }
]
});
// initialize value
showSelectedHeadersMenu.selectedValue = wjGrid.HeadersVisibility.None;
// create Show Marquee menu
let showMarqueeMenu = new wjInput.Menu('#showMarqueeMenu', {
// update header to show current selection
selectedIndexChanged: function (s, e) {
if (s.selectedIndex > -1) {
formatMenuHeader(s);
theGrid.showMarquee = s.selectedValue;
}
},
header: 'Show Marquee',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: 'On', value: true },
{ header: 'Off', value: false }
]
});
// initialize value
showMarqueeMenu.selectedValue = false;
// create Data Maps menu
let dataMapsMenu = new wjInput.Menu('#dataMapsMenu', {
// update header to show current selection
selectedIndexChanged: function (s, e) {
if (s.selectedIndex > -1) {
formatMenuHeader(s);
updateDataMaps(s.selectedValue);
}
},
header: 'Data Maps',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: 'On', value: true },
{ header: 'Off', value: false }
]
});
// initialize value
dataMapsMenu.selectedValue = true;
// create Formatting menu
let formattingMenu = new wjInput.Menu('#formattingMenu', {
// update header to show current selection
selectedIndexChanged: function (s, e) {
if (s.selectedIndex > -1) {
formatMenuHeader(s);
updateFormatting(s.selectedValue);
}
},
header: 'Formatting',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: 'On', value: true },
{ header: 'Off', value: false }
]
});
// initialize value
formattingMenu.selectedValue = true;
// Create Culture menu
/*var cultureMenu = new wjInput.Menu('#cultureMenu', {
header: 'Culture',
displayMemberPath: 'header',
selectedValuePath: 'value',
itemsSource: [
{ header: 'English', value: 'en' },
{ header: 'Spanish', value: 'es' },
{ header: 'Italian', value: 'it' },
{ header: 'French', value: 'fr' },
{ header: 'German', value: 'de' },
{ header: 'Dutch', value: 'nl' },
{ header: 'Japanese', value: 'ja' },
{ header: 'Korean', value: 'ko' },
{ header: 'Chinese', value: 'zh-HK' },
],
selectedIndexChanged: function(s, e) {
if (s.selectedIndex > -1){
formatMenuHeader(s);
loadCulture(s.selectedValue);
}
}
});
cultureMenu.selectedValue = 'en';*/
document.querySelector('#toggleColumnVisibility').addEventListener('click', () => {
let col = theGrid.columns[0];
col.visible = !col.visible;
});
document.querySelector('#changeColumnSize').addEventListener('click', () => {
let col = theGrid.columns[0];
col.visible = true;
col.width = col.width < 0 ? 60 : -1;
col = theGrid.rowHeaders.columns[0];
col.width = col.width < 0 ? 40 : -1;
});
document.querySelector('#toggleRowVisibility').addEventListener('click', () => {
let row = theGrid.rows[0];
row.visible = !row.visible;
});
document.querySelector('#changeRowSize').addEventListener('click', () => {
let row = theGrid.rows[0];
row.visible = true;
row.height = row.height < 0 ? 80 : -1;
row = theGrid.columnHeaders.rows[0];
row.height = row.height < 0 ? 80 : -1;
});
document.querySelector('#changeDefaultRowSize').addEventListener('click', () => {
theGrid.rows.defaultSize = theGrid.rows.defaultSize == 28 ? 65 : 28;
});
document.querySelector('#changeScrollPosition').addEventListener('click', () => {
if (theGrid.scrollPosition.y == 0) {
var sz = theGrid.scrollSize;
theGrid.scrollPosition = new wjCore.Point(-sz.width / 2, -sz.height / 2);
}
else {
theGrid.scrollPosition = new wjCore.Point(0, 0);
}
});
function formatMenuHeader(menu) {
let index = menu.header.indexOf(':');
if (index !== -1) {
menu.header = menu.header.substring(0, menu.header.indexOf(':')) + wjCore.format(': <b>{header}</b>', menu.selectedItem);
}
else {
menu.header = menu.header + wjCore.format(': <b>{header}</b>', menu.selectedItem);
}
}
// apply/remove data maps
function updateDataMaps(dataMaps) {
if (theGrid) {
var colCountry = theGrid.columns.getColumn('countryId');
var colProduct = theGrid.columns.getColumn('productId');
var colColor = theGrid.columns.getColumn('colorId');
if (colCountry && colProduct && colColor) {
if (dataMaps) {
colCountry.showDropDown = true; // show drop-down for countries
colProduct.showDropDown = false; // don't show it for products
colColor.showDropDown = false; // or colors (just to show how)
colCountry.dataMap = buildDataMap(getCountries());
colProduct.dataMap = buildDataMap(getProducts());
colColor.dataMap = buildDataMap(getColors());
}
else {
colCountry.dataMap = null;
colProduct.dataMap = null;
colColor.dataMap = null;
}
}
}
}
// build a data map from a string array using the indices as keys
function buildDataMap(items) {
var map = [];
for (var i = 0; i < items.length; i++) {
map.push({ key: i, value: items[i] });
}
return new wjGrid.DataMap(map, 'key', 'value');
}
// apply/remove column formatting
function updateFormatting(fmt) {
if (theGrid) {
setColumnFormat('amount', fmt ? 'c' : null);
setColumnFormat('amount2', fmt ? 'c' : null);
setColumnFormat('discount', fmt ? 'p0' : null);
setColumnFormat('start', fmt ? 'MMM d yy' : null);
setColumnFormat('end', fmt ? 'HH:mm' : null);
}
}
function setColumnFormat(name, format) {
var col = theGrid.columns.getColumn(name);
if (col) {
col.format = format;
}
}
function formatCellRange(cellRange) {
let rng;
rng = '(' + cellRange.row + ';' + cellRange.col + ')';
if (!cellRange.isSingleCell) {
rng += '-(' + cellRange.row2 + ';' + cellRange.col2 + ')';
}
return rng;
}
function currentItemChanged() {
let curr = wjCore.format('{current:n0} / {count:n0}', {
current: theGrid.collectionView.currentPosition + 1,
count: theGrid.collectionView.items.length
});
document.querySelector('#inputCurrent').value = curr;
if (theGrid.collectionView.currentPosition === 0) {
document.querySelector('#first').setAttribute('disabled', 'true');
document.querySelector('#previous').setAttribute('disabled', 'true');
}
else {
document.querySelector('#first').removeAttribute('disabled');
document.querySelector('#previous').removeAttribute('disabled');
}
if (theGrid.collectionView.currentPosition === theGrid.collectionView.items.length - 1) {
document.querySelector('#last').setAttribute('disabled', 'true');
document.querySelector('#next').setAttribute('disabled', 'true');
}
else {
document.querySelector('#last').removeAttribute('disabled');
document.querySelector('#next').removeAttribute('disabled');
}
}
function filterFunction(item) {
let f = document.querySelector('#filter').value;
if (f && item) {
// split string into terms to enable multi-field searches such as 'us gadget red'
let terms = f.toUpperCase().split(' ');
// look for any term in any string field
for (let i = 0; i < terms.length; i++) {
let termFound = false;
for (let key in item) {
let value = item[key];
if (wjCore.isString(value) && value.toUpperCase().indexOf(terms[i]) > -1) {
termFound = true;
break;
}
}
// fail if any of the terms is not found
if (!termFound) {
return false;
}
}
}
// include item in view
return true;
}
/*function loadCulture(culture) {
// get culture url
var url = 'https://cdn.grapecity.com/wijmo/5.latest/controls/cultures/wijmo.culture.' + culture + '.min.js';
// apply new culture to page
var scripts = document.getElementsByTagName('script'),
script;
for (var i = 0; i < scripts.length; i++) {
script = scripts[i];
if (script.src.indexOf('/cultures/wijmo.culture.') > -1) {
script.parentElement.removeChild(script);
break;
}
}
script = document.createElement('script');
script.onload = updateControls();
script.src = url;
document.head.appendChild(script);
}
function updateControls() {
wjCore.Control.invalidateAll();
}*/
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>GrapeCity Wijmo FlexGrid 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>
<!-- search box -->
<div class="row">
<div class="col-md-6 col-xs-4">
<input id="filter" type="text" class="form-control app-pad" placeholder="Filter" />
</div>
<div class="col-md-6 col-xs-8">
<div class="pull-right wj-control wj-content wj-pager">
<div class="wj-input-group">
<span class="wj-input-group-btn">
<button id="first" class="wj-btn wj-btn-default" type="button">
<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 id="previous" class="wj-btn wj-btn-default" type="button">
<span class="wj-glyph-left"></span>
</button>
</span>
<input id="inputCurrent" type="text" class="wj-form-control" disabled>
<span class="wj-input-group-btn">
<button id="next" class="wj-btn wj-btn-default" type="button">
<span class="wj-glyph-right"></span>
</button>
</span>
<span class="wj-input-group-btn">
<button id="last" class="wj-btn wj-btn-default" type="button">
<span class="wj-glyph-right"></span>
<span class="wj-glyph-right" style="margin-left:-4px"></span>
</button>
</span>
</div>
</div>
</div>
</div>
<!-- the grid -->
<div id="theGrid">
</div>
</div>
<!-- commands -->
<div class="well">
<div class="grid-sort-group">
<!-- current selection -->
<p>Selection: <b><span id="cellRange"></span></b></p>
<!-- data size -->
<div id="itemCountMenu"></div>
<!-- allow add new -->
<div id="allowAddNewMenu"></div>
<!-- selection mode -->
<div id="selectionModeMenu"></div>
<!-- headers visibility -->
<div id="headersVisibilityMenu"></div>
<!-- highlight headers -->
<div id="showSelectedHeadersMenu"></div>
<!-- show marquee -->
<div id="showMarqueeMenu"></div>
<!-- data maps -->
<div id="dataMapsMenu"></div>
<!-- formatting -->
<div id="formattingMenu"></div>
<!-- culture -->
<!-- <div id="cultureMenu"></div> -->
<br />
<br />
<!-- testing the object model -->
<button id="toggleColumnVisibility" class="btn btn-default">
Show/Hide Column
</button>
<button id="changeColumnSize" class="btn btn-default">
Resize Column
</button>
<button id="toggleRowVisibility" class="btn btn-default">
Show/Hide Row
</button>
<button id="changeRowSize" class="btn btn-default">
Resize Row
</button>
<button id="changeDefaultRowSize" class="btn btn-default">
Default Row Size
</button>
<button id="changeScrollPosition" class="btn btn-default">
Scroll Position
</button>
</div>
</div>
</div>
</body>
</html>
import { CollectionView } from '@grapecity/wijmo';
let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'];
let products = ['Widget', 'Gadget', 'Doohickey'];
let colors = ['Black', 'White', 'Red', 'Green', 'Blue'];
// generate some random data
export function getData(count, currentChangedHdl) {
let data = [];
let dt = new Date();
// add count items
for (let i = 0; i < count; i++) {
// constants used to create data items
let date = new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60), countryId = Math.floor(Math.random() * countries.length), productId = Math.floor(Math.random() * products.length), colorId = Math.floor(Math.random() * colors.length);
// create the item
let item = {
id: i,
start: date,
end: date,
country: countries[countryId],
product: products[productId],
color: colors[colorId],
countryId: countryId,
productId: productId,
colorId: colorId,
amount: Math.random() * 10000 - 5000,
amount2: Math.random() * 10000 - 5000,
discount: Math.random() / 4,
active: i % 4 == 0,
};
// add an array (should not auto-bind)
item.sales = [];
for (var j = 0; j < 12; j++) {
item.sales.push(50 + 20 * (Math.random() - .5) + j);
}
// add an object (should not auto-bind)
item.someObject = {
name: i,
value: i
};
// add the item to the list
data.push(item);
}
// return a CollectionView so multiple controls bound to this source
// will be updated automatically (TFS 145538)
let cv = new CollectionView(data);
if (currentChangedHdl) {
cv.currentChanged.addHandler(currentChangedHdl);
}
return cv;
}
// get possible values for each field
export function getCountries() {
return countries;
}
export function getProducts() {
return products;
}
export function getColors() {
return colors;
}
.wj-flexgrid {
height: 400px;
margin: 6px 0;
}
.grid-sort-group .wj-menu, .grid-sort-group .btn {
margin: 2px 4px 2px 0;
}
import 'bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
import './styles.css';
//
import { Component, Inject, enableProdMode, NgModule, ViewChild } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import * as wjcCore from '@grapecity/wijmo';
import * as wjcGrid from '@grapecity/wijmo.grid';
import { WjGridModule } from '@grapecity/wijmo.angular2.grid';
import { WjInputModule } from '@grapecity/wijmo.angular2.input';
import { AppPipesModule } from './app.pipe';
import { DataService } from './app.data';
//
@Component({
selector: 'app-component',
templateUrl: 'src/app.component.html'
})
export class AppComponent {
private _itemCount = 500;
private _culture = 'en';
private _dataMaps = true;
private _formatting = true;
private _filter = '';
private _toFilter: any;
private _thisFilterFunction: wjcCore.IPredicate;
private _groupBy = '';
private _pageSize = 0;
protected dataSvc: DataService;
data: any[];
// references FlexGrid named 'flex' in the view
@ViewChild('flex') flex: wjcGrid.FlexGrid;
// DataSvc will be passed by derived classes
constructor( @Inject(DataService) dataSvc: DataService) {
this.dataSvc = dataSvc;
this._thisFilterFunction = this._filterFunction.bind(this);
this.data = dataSvc.getData(this.itemCount);
}
get itemCount(): number {
return this._itemCount;
}
set itemCount(value: number) {
if (this._itemCount != value) {
this._itemCount = value;
this.data = this.dataSvc.getData(this.itemCount);
this.groupBy = '';
}
}
get dataMaps(): boolean {
return this._dataMaps;
}
set dataMaps(value: boolean) {
if (this._dataMaps != value) {
this._dataMaps = value;
this._updateDataMaps();
}
}
get formatting(): boolean {
return this._formatting;
}
set formatting(value: boolean) {
if (this._formatting != value) {
this._formatting = value;
this._updateFormatting();
}
}
get culture(): string {
return this._culture;
}
set culture(value: string) {
if (this._culture != value) {
this._culture = value;
this._loadCultureInfo();
}
}
get filter(): string {
return this._filter;
}
set filter(value: string) {
if (this._filter != value) {
this._filter = value;
this._applyFilter();
}
}
get groupBy(): string {
return this._groupBy;
}
set groupBy(value: string) {
if (this._groupBy != value) {
this._groupBy = value;
this._applyGroupBy();
}
}
get pageSize(): number {
return this._pageSize;
}
set pageSize(value: number) {
if (this._pageSize != value) {
this._pageSize = value;
if (this.flex) {
(<wjcCore.IPagedCollectionView>this.flex.collectionView).pageSize = value;
}
}
}
ngAfterViewInit() {
if (this.flex) {
this.updateDataMapSettings();
}
}
// update data maps, formatting, paging now and when the itemsSource changes
itemsSourceChangedHandler() {
var flex = this.flex;
if (!flex) {
return;
}
// make columns 25% wider (for readability and to show how)
for (var i = 0; i < flex.columns.length; i++) {
flex.columns[i].width = flex.columns[i].renderSize * 1.25;
}
// update data maps and formatting
this.updateDataMapSettings();
// set page size on the grid's internal collectionView
if (flex.collectionView && this.pageSize) {
(<wjcCore.IPagedCollectionView>flex.collectionView).pageSize = this.pageSize;
}
};
updateDataMapSettings() {
this._updateDataMaps();
this._updateFormatting();
}
toggleColumnVisibility() {
var flex = this.flex;
var col = flex.columns[0];
col.visible = !col.visible;
};
changeColumnSize() {
var flex = this.flex;
var col = flex.columns[0];
col.visible = true;
col.width = col.width < 0 ? 60 : -1;
col = flex.rowHeaders.columns[0];
col.width = col.width < 0 ? 40 : -1;
};
toggleRowVisibility() {
var flex = this.flex;
var row = flex.rows[0];
row.visible = !row.visible;
};
changeRowSize() {
var flex = this.flex;
var row = flex.rows[0];
row.visible = true;
row.height = row.height < 0 ? 80 : -1;
row = flex.columnHeaders.rows[0];
row.height = row.height < 0 ? 80 : -1;
};
changeDefaultRowSize() {
var flex = this.flex;
flex.rows.defaultSize = flex.rows.defaultSize == 28 ? 65 : 28;
};
changeScrollPosition() {
var flex = this.flex;
if (flex.scrollPosition.y == 0) {
var sz = flex.scrollSize;
flex.scrollPosition = new wjcCore.Point(-sz.width / 2, -sz.height / 2);
} else {
flex.scrollPosition = new wjcCore.Point(0, 0);
}
};
// apply/remove data maps
private _updateDataMaps() {
var flex = this.flex;
if (flex) {
var colCountry = flex.columns.getColumn('countryId');
var colProduct = flex.columns.getColumn('productId');
var colColor = flex.columns.getColumn('colorId');
if (colCountry && colProduct && colColor) {
if (this.dataMaps == true) {
colCountry.showDropDown = true; // show drop-down for countries
colProduct.showDropDown = false; // don't show it for products
colColor.showDropDown = false; // or colors (just to show how)
colCountry.dataMap = this._buildDataMap(this.dataSvc.getCountries());
colProduct.dataMap = this._buildDataMap(this.dataSvc.getProducts());
colColor.dataMap = this._buildDataMap(this.dataSvc.getColors());
} else {
colCountry.dataMap = null;
colProduct.dataMap = null;
colColor.dataMap = null;
}
}
}
}
// build a data map from a string array using the indices as keys
private _buildDataMap(items: any[]): wjcGrid.DataMap {
var map = [];
for (var i = 0; i < items.length; i++) {
map.push({ key: i, value: items[i] });
}
return new wjcGrid.DataMap(map, 'key', 'value');
}
// apply/remove column formatting
private _updateFormatting() {
var flex = this.flex;
if (flex) {
var fmt = this.formatting;
this._setColumnFormat('amount', fmt ? 'c' : null);
this._setColumnFormat('amount2', fmt ? 'c' : null);
this._setColumnFormat('discount', fmt ? 'p0' : null);
this._setColumnFormat('start', fmt ? 'MMM d yy' : null);
this._setColumnFormat('end', fmt ? 'HH:mm' : null);
}
}
private _setColumnFormat(name: string, format: string) {
var col = this.flex.columns.getColumn(name);
if (col) {
col.format = format;
}
}
private _loadCultureInfo() {
wjcCore.httpRequest('bin/Devel/sources/cultures/wijmo.culture.' + this.culture + '.js', {
dataType: 'script',
success: (xhr: XMLHttpRequest) => {
eval(xhr.response);
wjcCore.Control.invalidateAll();
}
});
}
// ICollectionView filter function
private _filterFunction(item: any) {
var f = this.filter;
if (f && item) {
// split string into terms to enable multi-field searches such as 'us gadget red'
var terms = f.toUpperCase().split(' ');
// look for any term in any string field
for (var i = 0; i < terms.length; i++) {
var termFound = false;
for (var key in item) {
var value = item[key];
if (wjcCore.isString(value) && value.toUpperCase().indexOf(terms[i]) > -1) {
termFound = true;
break;
}
}
// fail if any of the terms is not found
if (!termFound) {
return false;
}
}
}
// include item in view
return true;
}
// apply filter (applied on a 500 ms timeOut)
protected _applyFilter() {
if (this._toFilter) {
clearTimeout(this._toFilter);
}
var self = this;
this._toFilter = setTimeout(function () {
self._toFilter = null;
if (self.flex) {
var cv = self.flex.collectionView;
if (cv) {
if (cv.filter != self._thisFilterFunction) {
cv.filter = self._thisFilterFunction;
} else {
cv.refresh();
}
}
}
}, 500);
}
private _applyGroupBy() {
if (this.flex) {
// get the collection view, start update
var cv = this.flex.collectionView;
cv.beginUpdate();
// clear existing groups
cv.groupDescriptions.clear();
// add new groups
var groupNames = this.groupBy.split('/'),
groupDesc;
for (var i = 0; i < groupNames.length; i++) {
var propName = groupNames[i].toLowerCase();
if (propName == 'amount') {
// group amounts in ranges
// (could use the mapping function to group countries into continents,
// names into initials, etc)
groupDesc = new wjcCore.PropertyGroupDescription(propName, function (item:any, prop: string) {
var value = item[prop];
if (value > 1000) return 'Large Amounts';
if (value > 100) return 'Medium Amounts';
if (value > 0) return 'Small Amounts';
return 'Negative';
});
cv.groupDescriptions.push(groupDesc);
} else if (propName) {
// group other properties by their specific values
groupDesc = new wjcCore.PropertyGroupDescription(propName);
cv.groupDescriptions.push(groupDesc);
}
}
// done updating
cv.endUpdate();
}
}
}
//
@NgModule({
imports: [WjInputModule, WjGridModule, AppPipesModule, BrowserModule, FormsModule],
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 Wijmo FlexGrid Overview</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">
<!-- search box -->
<div class="row">
<div class="col-md-6 col-xs-4">
<input type="text" class="form-control app-pad" placeholder="Filter" [(ngModel)]="filter" />
</div>
<div class="col-md-6 col-xs-8">
<wj-collection-view-navigator [cv]="flex.collectionView" class="pull-right">
</wj-collection-view-navigator>
</div>
</div>
<!-- the grid -->
<wj-flex-grid #flex
class="grid"
[allowResizing]="'Both'"
[itemsSource]="data"
[allowMerging]="'All'"
[stickyHeaders]="true"
(itemsSourceChanged)="itemsSourceChangedHandler()">
</wj-flex-grid>
<!-- commands -->
<div class="well">
<div class="grid-sort-group">
<!-- current selection -->
<p>Selection: <b>{{flex.selection | cellRange}}</b></p>
<!-- data size -->
<wj-menu [(value)]="itemCount" [header]="'Items'">
<wj-menu-item [value]="5">5</wj-menu-item>
<wj-menu-item [value]="50">50</wj-menu-item>
<wj-menu-item [value]="500">500</wj-menu-item>
<wj-menu-item [value]="5000">5,000</wj-menu-item>
<wj-menu-item [value]="50000">50,000</wj-menu-item>
<wj-menu-item [value]="100000">100,000</wj-menu-item>
<wj-menu-item [value]="500000">500,000</wj-menu-item>
<wj-menu-item [value]="1000000">1,000,000</wj-menu-item>
</wj-menu>
<!-- allow add new -->
<wj-menu [(value)]="flex.allowAddNew" [header]="'Allow Add'">
<wj-menu-item [value]="true">True</wj-menu-item>
<wj-menu-item [value]="false">False</wj-menu-item>
</wj-menu>
<!-- selection mode -->
<wj-menu [(value)]="flex.selectionMode" [header]="'Selection'">
<wj-menu-item [value]="0">None</wj-menu-item>
<wj-menu-item [value]="1">Cell</wj-menu-item>
<wj-menu-item [value]="2">CellRange</wj-menu-item>
<wj-menu-item [value]="3">Row</wj-menu-item>
<wj-menu-item [value]="4">RowRange</wj-menu-item>
<wj-menu-item [value]="5">ListBox</wj-menu-item>
</wj-menu>
<!-- headers visibility -->
<wj-menu [(value)]="flex.headersVisibility" [header]="'Headers Visibility'">
<wj-menu-item [value]="0">None</wj-menu-item>
<wj-menu-item [value]="1">Column</wj-menu-item>
<wj-menu-item [value]="2">Row</wj-menu-item>
<wj-menu-item [value]="3">All</wj-menu-item>
</wj-menu>
<!-- highlight headers -->
<wj-menu [(value)]="flex.showSelectedHeaders" [header]="'Show Selected Headers'">
<wj-menu-item [value]="0">None</wj-menu-item>
<wj-menu-item [value]="1">Column</wj-menu-item>
<wj-menu-item [value]="2">Row</wj-menu-item>
<wj-menu-item [value]="3">All</wj-menu-item>
</wj-menu>
<!-- show marquee -->
<wj-menu [(value)]="flex.showMarquee" [header]="'Show Marquee'">
<wj-menu-item [value]="true">Yes</wj-menu-item>
<wj-menu-item [value]="false">No</wj-menu-item>
</wj-menu>
<!-- data maps -->
<wj-menu [(value)]="dataMaps" [header]="'Data Maps'">
<wj-menu-item [value]="true">On</wj-menu-item>
<wj-menu-item [value]="false">Off</wj-menu-item>
</wj-menu>
<!-- formatting -->
<wj-menu [(value)]="formatting" [header]="'Formatting'">
<wj-menu-item [value]="true">On</wj-menu-item>
<wj-menu-item [value]="false">Off</wj-menu-item>
</wj-menu>
<!-- culture -->
<!-- <wj-menu [(value)]="culture" [header]="'Culture'">
<wj-menu-item [value]="'en'">English</wj-menu-item>
<wj-menu-item [value]="'de'">German</wj-menu-item>
<wj-menu-item [value]="'it'">Italian</wj-menu-item>
<wj-menu-item [value]="'fr'">French</wj-menu-item>
<wj-menu-item [value]="'pt'">Portuguese</wj-menu-item>
<wj-menu-item [value]="'ru'">Russian</wj-menu-item>
<wj-menu-item [value]="'ja'">Japanese</wj-menu-item>
<wj-menu-item [value]="'ko'">Korean</wj-menu-item>
</wj-menu> -->
<br />
<br />
<!-- testing the object model -->
<button class="btn btn-default" (click)="toggleColumnVisibility()">
Show/Hide Column
</button>
<button class="btn btn-default" (click)="changeColumnSize()">
Resize Column
</button>
<button class="btn btn-default" (click)="toggleRowVisibility()">
Show/Hide Row
</button>
<button class="btn btn-default" (click)="changeRowSize()">
Resize Row
</button>
<button class="btn btn-default" (click)="changeDefaultRowSize()">
Default Row Size
</button>
<button class="btn btn-default" (click)="changeScrollPosition()">
Scroll Position
</button>
</div>
</div>
</div>
import { Injectable } from '@angular/core';
@Injectable()
export class DataService {
// data used to generate random items
private _products = ['Widget', 'Gadget', 'Doohickey'];
private _colors = ['Black', 'White', 'Red', 'Green', 'Blue'];
private _someCountries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'];
getCountries(): string[] {
return this._someCountries;
}
getProducts(): string[] {
return this._products;
}
getColors(): string[] {
return this._colors;
}
// get matches for a search term
getData(count: number): any[] {
var data = [];
var dt = new Date();
// add count items
for (var i = 0; i < count; i++) {
// constants used to create data items
var date = new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60),
countryId = Math.floor(Math.random() * this._someCountries.length),
productId = Math.floor(Math.random() * this._products.length),
colorId = Math.floor(Math.random() * this._colors.length);
// create the item
var item = {
id: i,
start: date,
end: new Date(date.getTime() + Math.random() * 30 * (24 * 60 * 60 * 1000)),
country: this._someCountries[countryId],
product: this._products[productId],
color: this._colors[colorId],
countryId: countryId,
productId: productId,
colorId: colorId,
amount: Math.random() * 10000 - 5000,
amount2: Math.random() * 10000 - 5000,
discount: Math.random() / 4,
active: i % 4 == 0
};
// add the item to the list
data.push(item);
}
return data;
}
}
.wj-flexgrid {
height: 400px;
margin: 6px 0;
}
.grid-sort-group .wj-menu, .grid-sort-group .btn {
margin: 2px 2px 2px 0;
}
<template>
<div class="container-fluid">
<!-- search box -->
<div class="row">
<div class="col-md-6 col-xs-4">
<input
type="text"
class="form-control app-pad"
placeholder="Filter"
v-model="filter"
>
</div>
<div class="col-md-6 col-xs-8">
<div class="pull-right wj-control wj-content wj-pager">
<div class="wj-input-group">
<span class="wj-input-group-btn">
<button id="first" class="wj-btn wj-btn-default" type="button">
<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 id="previous" class="wj-btn wj-btn-default" type="button">
<span class="wj-glyph-left"></span>
</button>
</span>
<input id="inputCurrent" type="text" class="wj-form-control" disabled>
<span class="wj-input-group-btn">
<button id="next" class="wj-btn wj-btn-default" type="button">
<span class="wj-glyph-right"></span>
</button>
</span>
<span class="wj-input-group-btn">
<button id="last" class="wj-btn wj-btn-default" type="button">
<span class="wj-glyph-right"></span>
<span class="wj-glyph-right" style="margin-left:-4px"></span>
</button>
</span>
</div>
</div>
</div>
</div>
<!-- the grid -->
<wj-flex-grid
:initialized="initialized"
class="grid"
:itemsSourceChanged="itemsSourceChangedHandler"
:allowResizing="'Both'"
:allowMerging="'All'"
:stickyHeaders="true"
></wj-flex-grid>
<!-- commands -->
<div class="well">
<div class="grid-sort-group">
<!-- current selection -->
<p>
Selection:
<b>{{selection}}</b>
</p>
<!-- data size -->
<wj-menu
:header="'Items'"
:itemsSource="itemCountSource"
:displayMemberPath="'header'"
:selectedValuePath="'value'"
:selectedIndexChanged="selectedIndexChanged.bind(this,'itemCount')"
:initialized="initMenu.bind(this,'itemCount')"
></wj-menu>
<!-- allow add new -->
<wj-menu
:header="'Allow Add'"
:itemsSource="addNewRowSource"
:displayMemberPath="'header'"
:selectedValuePath="'value'"
:selectedIndexChanged="selectedIndexChanged.bind(this,'allowAddNew')"
:initialized="initMenu.bind(this,'allowAddNew')"
></wj-menu>
<!-- selection mode -->
<wj-menu
:header="'Selection'"
:itemsSource="selectionModeSource"
:displayMemberPath="'header'"
:selectedValuePath="'value'"
:selectedIndexChanged="selectedIndexChanged.bind(this,'selectionMode')"
:initialized="initMenu.bind(this,'selectionMode')"
></wj-menu>
<!-- headers visibility -->
<wj-menu
:header="'Headers Visibility'"
:itemsSource="headersVisibilitySource"
:displayMemberPath="'header'"
:selectedValuePath="'value'"
:selectedIndexChanged="selectedIndexChanged.bind(this,'headersVisibility')"
:initialized="initMenu.bind(this,'headersVisibility')"
></wj-menu>
<!-- highlight headers -->
<wj-menu
:header="'Show Selected Headers'"
:itemsSource="howSelectedHeadersSource"
:displayMemberPath="'header'"
:selectedValuePath="'value'"
:selectedIndexChanged="selectedIndexChanged.bind(this,'showSelectedHeaders')"
:initialized="initMenu.bind(this,'showSelectedHeaders')"
></wj-menu>
<!-- show marquee -->
<wj-menu
:header="'Show Marquee'"
:itemsSource="showMarqueeSource"
:displayMemberPath="'header'"
:selectedValuePath="'value'"
:selectedIndexChanged="selectedIndexChanged.bind(this,'showMarquee')"
:initialized="initMenu.bind(this,'showMarquee')"
></wj-menu>
<!-- data maps -->
<wj-menu
:header="'Data Maps'"
:itemsSource="dataMapsSource"
:displayMemberPath="'header'"
:selectedValuePath="'value'"
:selectedIndexChanged="selectedIndexChanged.bind(this,'dataMaps')"
:initialized="initMenu.bind(this,'dataMaps')"
></wj-menu>
<!-- formatting -->
<wj-menu
:header="'Formatting'"
:itemsSource="formattingSource"
:displayMemberPath="'header'"
:selectedValuePath="'value'"
:selectedIndexChanged="selectedIndexChanged.bind(this,'formatting')"
:initialized="initMenu.bind(this,'formatting')"
></wj-menu>
<br>
<br>
<!-- testing the object model -->
<button class="btn btn-default" @click="toggleColumnVisibility()">Show/Hide Column</button>
<button class="btn btn-default" @click="changeColumnSize()">Resize Column</button>
<button class="btn btn-default" @click="toggleRowVisibility()">Show/Hide Row</button>
<button class="btn btn-default" @click="changeRowSize()">Resize Row</button>
<button class="btn btn-default" @click="changeDefaultRowSize()">Default Row Size</button>
<button class="btn btn-default" @click="changeScrollPosition()">Scroll Position</button>
</div>
</div>
</div>
</template>
<script>
import "@grapecity/wijmo.styles/wijmo.css";
import "bootstrap.css";
import * as wjcCore from "@grapecity/wijmo";
import * as wjcGrid from "@grapecity/wijmo.grid";
import Vue from "vue";
import { getCountries, getProducts, getColors, getData } from "./data";
import "@grapecity/wijmo.vue2.grid";
import "@grapecity/wijmo.vue2.input";
new Vue({
el: "#app",
data: {
itemCountField: 500,
cultureField: "en",
dataMapsField: true,
formattingField: true,
filterField: "",
toFilterField: null,
thisFilterFunctionField: null,
groupByField: "",
pageSizeField: 0,
collectionViewField: null,
selectionField: null,
allowAddNewField: null,
selectionModeField: null,
headersVisibilityField: null,
showSelectedHeadersField: null,
showMarqueeField: null,
itemCountSource: [
{ header: "5", value: 5 },
{ header: "50", value: 50 },
{ header: "500", value: 500 },
{ header: "5,000", value: 5000 },
{ header: "50,000", value: 50000 },
{ header: "100,000", value: 100000 },
{ header: "500,000", value: 500000 },
{ header: "1,000,000", value: 1000000 }
],
addNewRowSource: [
{ header: "Yes", value: true },
{ header: "No", value: false }
],
selectionModeSource: [
{ header: "None", value: wjcGrid.SelectionMode.None },
{ header: "Cell", value: wjcGrid.SelectionMode.Cell },
{ header: "CellRange", value: wjcGrid.SelectionMode.CellRange },
{ header: "Row", value: wjcGrid.SelectionMode.Row },
{ header: "RowRange", value: wjcGrid.SelectionMode.RowRange },
{ header: "ListBox", value: wjcGrid.SelectionMode.ListBox }
],
headersVisibilitySource: [
{ header: "None", value: wjcGrid.HeadersVisibility.None },
{ header: "Column", value: wjcGrid.HeadersVisibility.Column },
{ header: "Row", value: wjcGrid.HeadersVisibility.Row },
{ header: "All", value: wjcGrid.HeadersVisibility.All }
],
howSelectedHeadersSource: [
{ header: "None", value: wjcGrid.HeadersVisibility.None },
{ header: "Column", value: wjcGrid.HeadersVisibility.Column },
{ header: "Row", value: wjcGrid.HeadersVisibility.Row },
{ header: "All", value: wjcGrid.HeadersVisibility.All }
],
showMarqueeSource: [
{ header: "On", value: true },
{ header: "Off", value: false }
],
dataMapsSource: [
{ header: "On", value: true },
{ header: "Off", value: false }
],
formattingSource: [
{ header: "On", value: true },
{ header: "Off", value: false }
]
},
methods: {
initialized: function(flex) {
this.flex = flex;
this.collectionView = this.flex.collectionView;
this.selection = this.flex.selection;
this.allowAddNew = this.flex.allowAddNew;
this.selectionMode = this.flex.selectionMode;
this.headersVisibility = this.flex.headersVisibility;
this.showSelectedHeaders = this.flex.showSelectedHeaders;
this.showMarquee = this.flex.showMarquee;
this.flex.select(new wjcGrid.CellRange(0, 0));
this.flex.selectionChanged.addHandler((s, e) => {
this.selection = e.range;
});
this.flex.itemsSource = getData(this.itemCount);
},
formatMenuHeader: function(menu) {
let index = menu.header.indexOf(":");
if (index !== -1) {
menu.header =
menu.header.substring(0, menu.header.indexOf(":")) +
wjcCore.format(": <b>{header}</b>", menu.selectedItem);
} else {
menu.header =
menu.header +
wjcCore.format(": <b>{header}</b>", menu.selectedItem);
}
},
// update data maps, formatting, paging now and when the itemsSource changes
itemsSourceChangedHandler: function() {
var flex = this.flex;
if (!flex) {
return;
}
// make columns 25% wider (for readability and to show how)
for (var i = 0; i < flex.columns.length; i++) {
flex.columns[i].width = flex.columns[i].renderSize * 1.25;
}
// update data maps and formatting
this.updateDataMapSettings();
// set page size on the grid's internal collectionView
if (flex.collectionView && this.pageSize) {
flex.collectionView.pageSize = this.pageSize;
}
},
updateDataMapSettings: function() {
this._updateDataMaps();
this._updateFormatting();
},
toggleColumnVisibility: function() {
var flex = this.flex;
var col = flex.columns[0];
col.visible = !col.visible;
},
changeColumnSize: function() {
var flex = this.flex;
var col = flex.columns[0];
col.visible = true;
col.width = col.width < 0 ? 60 : -1;
col = flex.rowHeaders.columns[0];
col.width = col.width < 0 ? 40 : -1;
},
toggleRowVisibility: function() {
var flex = this.flex;
var row = flex.rows[0];
row.visible = !row.visible;
},
changeRowSize: function() {
var flex = this.flex;
var row = flex.rows[0];
row.visible = true;
row.height = row.height < 0 ? 80 : -1;
row = flex.columnHeaders.rows[0];
row.height = row.height < 0 ? 80 : -1;
},
changeDefaultRowSize: function() {
var flex = this.flex;
flex.rows.defaultSize = flex.rows.defaultSize == 28 ? 65 : 28;
},
changeScrollPosition: function() {
var flex = this.flex;
if (flex.scrollPosition.y == 0) {
var sz = flex.scrollSize;
flex.scrollPosition = new wjcCore.Point(
-sz.width / 2,
-sz.height / 2
);
} else {
flex.scrollPosition = new wjcCore.Point(0, 0);
}
},
// apply/remove data maps
_updateDataMaps: function() {
var flex = this.flex;
if (flex) {
var colCountry = flex.columns.getColumn("countryId");
var colProduct = flex.columns.getColumn("productId");
var colColor = flex.columns.getColumn("colorId");
if (colCountry && colProduct && colColor) {
if (this.dataMaps == true) {
colCountry.showDropDown = true; // show drop-down for countries
colProduct.showDropDown = false; // don't show it for products
colColor.showDropDown = false; // or colors (just to show how)
colCountry.dataMap = this._buildDataMap(getCountries());
colProduct.dataMap = this._buildDataMap(getProducts());
colColor.dataMap = this._buildDataMap(getColors());
} else {
colCountry.dataMap = null;
colProduct.dataMap = null;
colColor.dataMap = null;
}
}
}
},
// build a data map from a string array using the indices as keys
_buildDataMap: function(items) {
var map = [];
for (var i = 0; i < items.length; i++) {
map.push({ key: i, value: items[i] });
}
return new wjcGrid.DataMap(map, "key", "value");
},
// apply/remove column formatting
_updateFormatting: function() {
var flex = this.flex;
if (flex) {
var fmt = this.formatting;
this._setColumnFormat("amount", fmt ? "c" : null);
this._setColumnFormat("amount2", fmt ? "c" : null);
this._setColumnFormat("discount", fmt ? "p0" : null);
this._setColumnFormat("start", fmt ? "MMM d yy" : null);
this._setColumnFormat("end", fmt ? "HH:mm" : null);
}
},
_setColumnFormat: function(name, format) {
var col = this.flex.columns.getColumn(name);
if (col) {
col.format = format;
}
},
_loadCultureInfo: function() {
wjcCore.httpRequest(
"bin/Devel/sources/cultures/wijmo.culture." +
this.culture +
".js",
{
dataType: "script",
success: xhr => {
eval(xhr.response);
wjcCore.Control.invalidateAll();
}
}
);
},
// ICollectionView filter function
filterFieldFunction: function(item) {
var f = this.filter;
if (f && item) {
// split string into terms to enable multi-field searches such as 'us gadget red'
var terms = f.toUpperCase().split(" ");
// look for any term in any string field
for (var i = 0; i < terms.length; i++) {
var termFound = false;
for (var key in item) {
var value = item[key];
if (
wjcCore.isString(value) &&
value.toUpperCase().indexOf(terms[i]) > -1
) {
termFound = true;
break;
}
}
// fail if any of the terms is not found
if (!termFound) {
return false;
}
}
}
// include item in view
return true;
},
// apply filter (applied on a 500 ms timeOut)
_applyFilter: function() {
if (this.toFilterField) {
clearTimeout(this.toFilterField);
}
var self = this;
this.toFilterField = setTimeout(function() {
self.toFilterField = null;
if (self.flex) {
var cv = self.flex.collectionView;
if (cv) {
if (cv.filter != self.filterFieldFunction) {
cv.filter = self.filterFieldFunction;
} else {
cv.refresh();
}
}
}
}, 500);
},
_applyGroupBy: function() {
if (this.flex) {
// get the collection view, start update
var cv = this.flex.collectionView;
cv.beginUpdate();
// clear existing groups
cv.groupDescriptions.clear();
// add new groups
var groupNames = this.groupBy.split("/"),
groupDesc;
for (var i = 0; i < groupNames.length; i++) {
var propName = groupNames[i].toLowerCase();
if (propName == "amount") {
// group amounts in ranges
// (could use the mapping function to group countries into continents,
// names into initials, etc)
groupDesc = new wjcCore.PropertyGroupDescription(
propName,
function(item, prop) {
var value = item[prop];
if (value > 1000) return "Large Amounts";
if (value > 100) return "Medium Amounts";
if (value > 0) return "Small Amounts";
return "Negative";
}
);
cv.groupDescriptions.push(groupDesc);
} else if (propName) {
// group other properties by their specific values
groupDesc = new wjcCore.PropertyGroupDescription(
propName
);
cv.groupDescriptions.push(groupDesc);
}
}
// done updating
cv.endUpdate();
}
},
selectedIndexChanged: function(prop, s, e) {
if (s.selectedIndex > -1) {
this.formatMenuHeader(s);
this[prop] = s.selectedValue;
}
},
initEvent: function() {
document.querySelector("#first").addEventListener("click", () => {
this.flex.collectionView.moveCurrentToFirst();
this.currentItemChanged();
});
document
.querySelector("#previous")
.addEventListener("click", () => {
this.flex.collectionView.moveCurrentToPrevious();
this.currentItemChanged();
});
document.querySelector("#next").addEventListener("click", () => {
this.flex.collectionView.moveCurrentToNext();
this.currentItemChanged();
});
document.querySelector("#last").addEventListener("click", () => {
this.flex.collectionView.moveCurrentToLast();
this.currentItemChanged();
});
},
currentItemChanged: function() {
let curr = wjcCore.format("{current:n0} / {count:n0}", {
current: this.flex.collectionView.currentPosition + 1,
count: this.flex.collectionView.items.length
});
document.querySelector("#inputCurrent").value = curr;
if (this.flex.collectionView.currentPosition === 0) {
document
.querySelector("#first")
.setAttribute("disabled", "true");
document
.querySelector("#previous")
.setAttribute("disabled", "true");
} else {
document.querySelector("#first").removeAttribute("disabled");
document.querySelector("#previous").removeAttribute("disabled");
}
if (
this.flex.collectionView.currentPosition ===
this.flex.collectionView.items.length - 1
) {
document
.querySelector("#last")
.setAttribute("disabled", "true");
document
.querySelector("#next")
.setAttribute("disabled", "true");
} else {
document.querySelector("#last").removeAttribute("disabled");
document.querySelector("#next").removeAttribute("disabled");
}
},
initMenu: function(type, s) {
this.formatMenuHeader(s);
switch (type) {
case "itemCount":
s.selectedValue = this.itemCount;
return;
case "allowAddNew":
s.selectedValue = this.allowAddNew;
return;
case "selectionMode":
s.selectedValue = this.selectionMode;
return;
case "headersVisibility":
s.selectedValue = this.headersVisibility;
return;
case "showSelectedHeaders":
s.selectedValue = this.showSelectedHeaders;
return;
case "showMarquee":
s.selectedValue = false;
return;
case "dataMaps":
s.selectedValue = true;
return;
case "formatting":
s.selectedValue = true;
return;
}
},
filterFunction: function(item) {
var f = this.filter;
if (f && item) {
// split string into terms to enable multi-field searches such as 'us gadget red'
var terms = f.toUpperCase().split(" ");
// look for any term in any string field
for (var i = 0; i < terms.length; i++) {
var termFound = false;
for (var key in item) {
var value = item[key];
if (
wjcCore.isString(value) &&
value.toUpperCase().indexOf(terms[i]) > -1
) {
termFound = true;
break;
}
}
// fail if any of the terms is not found
if (!termFound) {
return false;
}
}
}
// include item in view
return true;
}
},
mounted: function() {
this.initEvent();
this.thisFilterFunction = this.filterFieldFunction.bind(this);
this.flex.itemsSouce = getData(this.itemCount);
if (this.flex) {
this.updateDataMapSettings();
}
this.currentItemChanged();
},
computed: {
collectionView: {
get: function() {
return this.collectionViewField;
},
set: function(value) {
this.collectionViewField = value;
}
},
selection: {
get: function() {
var value = this.selectionField;
var rng = "";
if (value instanceof wjcGrid.CellRange) {
rng = "(" + value.row + ";" + value.col + ")";
if (!value.isSingleCell) {
rng += "-(" + value.row2 + ";" + value.col2 + ")";
}
}
return rng;
},
set: function(value) {
this.selectionField = value;
}
},
allowAddNew: {
get: function() {
return this.allowAddNewField;
},
set: function(value) {
this.allowAddNewField = value;
if (this.flex) {
this.flex.allowAddNew = value;
}
}
},
selectionMode: {
get: function() {
return this.selectionModeField;
},
set: function(value) {
this.selectionModeField = value;
if (this.flex) {
this.flex.selectionMode = value;
}
}
},
headersVisibility: {
get: function() {
return this.headersVisibilityField;
},
set: function(value) {
this.headersVisibilityField = value;
if (this.flex) {
this.flex.headersVisibility = value;
}
}
},
showSelectedHeaders: {
get: function() {
return this.showSelectedHeadersField;
},
set: function(value) {
this.showSelectedHeadersField = value;
if (this.flex) {
this.flex.showSelectedHeaders = value;
}
}
},
showMarquee: {
get: function() {
return this.showMarqueeField;
},
set: function(value) {
this.showMarqueeField = value;
if (this.flex) {
this.flex.showMarquee = value;
}
}
},
itemCount: {
get: function() {
return this.itemCountField;
},
set: function(value) {
if (this.itemCountField != value) {
this.itemCountField = value;
this.flex.itemsSource = getData(this.itemCount);
this.groupBy = "";
this.currentItemChanged();
}
}
},
dataMaps: {
get: function() {
return this.dataMapsField;
},
set: function(value) {
if (this.dataMapsField != value) {
this.dataMapsField = value;
this._updateDataMaps();
}
}
},
formatting: {
get: function() {
return this.formattingField;
},
set: function(value) {
if (this.formattingField != value) {
this.formattingField = value;
this._updateFormatting();
}
}
},
culture: {
get: function() {
return this.cultureField;
},
set: function(value) {
if (this.cultureField != value) {
this.cultureField = value;
this._loadCultureInfo();
}
}
},
filter: {
get: function() {
return this.filterField;
},
set: function(value) {
if (this.filterField != value) {
this.filterField = value;
this._applyFilter();
}
}
},
groupBy: {
get: function() {
return this.groupByField;
},
set: function(value) {
if (this.groupByField != value) {
this.groupByField = value;
this._applyGroupBy();
}
}
},
pageSize: {
get: function() {
return this.pageSizeField;
},
set: function(value) {
if (this.pageSizeField != value) {
this.pageSizeField = value;
if (this.flex) {
this.flex.collectionView.pageSize = value;
}
}
}
}
},
updated:function(s,e){
}
});
</script>
<style>
.wj-flexgrid {
height: 400px;
margin: 6px 0;
}
.grid-sort-group .wj-menu,
.grid-sort-group .btn {
margin: 2px 2px 2px 0;
}
</style>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>GrapeCity Wijmo FlexGrid 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.vue');
</script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
var _products = ['Widget', 'Gadget', 'Doohickey'];
var _colors = ['Black', 'White', 'Red', 'Green', 'Blue'];
var _someCountries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'];
export function getCountries() {
return _someCountries;
}
export function getProducts() {
return _products;
}
export function getColors() {
return _colors;
}
// get matches for a search term
export function getData(count) {
var data = [];
var dt = new Date();
// add count items
for (var i = 0; i < count; i++) {
// constants used to create data items
var date = new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60),
countryId = Math.floor(Math.random() * _someCountries.length),
productId = Math.floor(Math.random() * _products.length),
colorId = Math.floor(Math.random() * _colors.length);
// create the item
var item = {
id: i,
start: date,
end: new Date(date.getTime() + Math.random() * 30 * (24 * 60 * 60 * 1000)),
country: _someCountries[countryId],
product: _products[productId],
color: _colors[colorId],
countryId: countryId,
productId: productId,
colorId: colorId,
amount: Math.random() * 10000 - 5000,
amount2: Math.random() * 10000 - 5000,
discount: Math.random() / 4,
active: i % 4 == 0
};
// add the item to the list
data.push(item);
}
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 * as wijmo from '@grapecity/wijmo';
import * as grid from '@grapecity/wijmo.grid';
//
import * as wjInput from '@grapecity/wijmo.react.input';
import * as wjGrid from '@grapecity/wijmo.react.grid';
import { Navigator } from './navigator';
import { getData, getCountries, getProducts, getColors } from './data';
//
var MenuType;
(function (MenuType) {
MenuType[MenuType["allowAdd"] = 1] = "allowAdd";
MenuType[MenuType["dataMaps"] = 7] = "dataMaps";
MenuType[MenuType["formatting"] = 8] = "formatting";
MenuType[MenuType["headersVisibility"] = 2] = "headersVisibility";
MenuType[MenuType["itemsCount"] = 3] = "itemsCount";
MenuType[MenuType["selectionMode"] = 4] = "selectionMode";
MenuType[MenuType["showMarquee"] = 5] = "showMarquee";
MenuType[MenuType["showSelectedHeaders"] = 6] = "showSelectedHeaders";
})(MenuType || (MenuType = {}));
//
class App extends React.Component {
//
constructor(props) {
super(props);
this.Values = {
headersVisibility: ['None', 'Column', 'Row', 'All'],
itemsCount: [
{ value: 5, text: '5' },
{ value: 50, text: '50' },
{ value: 500, text: '500' },
{ value: 5000, text: '5,000' },
{ value: 50000, text: '50,000' },
{ value: 100000, text: '100,000' },
{ value: 500000, text: '500,000' },
{ value: 1000000, text: '1,000,000' }
],
onOff: [
{ value: true, text: 'On' },
{ value: false, text: 'Off' }
],
selectionMode: ['None', 'Cell', 'CellRange', 'Row', 'RowRange', 'ListBox'],
yesNo: [
{ value: true, text: 'Yes' },
{ value: false, text: 'No' }
]
};
//
this._toFilter = null;
this._itemsCount = 500;
this.state = {
allowAdd: false,
dataMaps: true,
filter: '',
formatting: true,
headersVisibility: 'All',
selectionMode: 'CellRange',
showMarquee: false,
showSelectedHeaders: 'None',
data: getData(this._itemsCount),
selection: ''
};
}
//
get allowAdd() {
return this.state.allowAdd;
}
set allowAdd(value) {
if (this.state.allowAdd !== value) {
this.setState({ allowAdd: value });
}
}
//
get dataMaps() {
return this.state.dataMaps;
}
set dataMaps(value) {
if (this.state.dataMaps !== value) {
this.setState({ dataMaps: value });
this._updateDataMaps();
}
}
//
get formatting() {
return this.state.formatting;
}
set formatting(value) {
if (this.state.formatting !== value) {
this.setState({ formatting: value });
this._updateFormatting();
}
}
//
get filter() {
return this.state.filter;
}
set filter(value) {
if (this.filter !== value) {
this.setState({ filter: value });
this._applyFilter();
}
}
//
get headersVisibility() {
return this.state.headersVisibility;
}
set headersVisibility(value) {
if (this.state.headersVisibility !== value) {
this.setState({ headersVisibility: value });
}
}
//
get itemsCount() {
return this._itemsCount;
}
set itemsCount(value) {
if (this._itemsCount !== value) {
this._itemsCount = value;
this.setState({ data: getData(value) });
}
}
//
get selectionMode() {
return this.state.selectionMode;
}
set selectionMode(value) {
if (this.state.selectionMode !== value) {
this.setState({ selectionMode: value });
}
}
//
get showMarquee() {
return this.state.showMarquee;
}
set showMarquee(value) {
if (this.state.showMarquee !== value) {
this.setState({ showMarquee: value });
}
}
//
get showSelectedHeaders() {
return this.state.showSelectedHeaders;
}
set showSelectedHeaders(value) {
if (this.state.showSelectedHeaders !== value) {
this.setState({ showSelectedHeaders: value });
}
}
//
componentDidMount() {
this._updateDataMapSettings();
}
//
render() {
return <div className='container-fluid'>
<div className='row'>
<div className='col-md-6 col-xs-4'>
<input type='text' className='form-control app-pad' placeholder='Filter' value={this.filter} onChange={this._filterChanged.bind(this)}/>
</div>
<div className='col-md-6 col-xs-8'>
<Navigator view={this.state.data} className='pull-right'>
</Navigator>
</div>
</div>
<wjGrid.FlexGrid allowAddNew={this.allowAdd} allowMerging='All' allowResizing='Both' headersVisibility={this.headersVisibility} selectionMode={this.selectionMode} showMarquee={this.showMarquee} showSelectedHeaders={this.showSelectedHeaders} stickyHeaders={true} itemsSource={this.state.data} initialized={this._gridInitialized.bind(this)} itemsSourceChanged={this._gridItemsSourceChanged.bind(this)} selectionChanged={this._gridSelectionChanged.bind(this)}>
</wjGrid.FlexGrid>
<div className='well'>
<div className='grid-sort-group form-group row'>
<p>Selection: <b>{this.state.selection}</b></p>
<wjInput.Menu header={'<b>Items:</b> ' + this._getText(this.Values.itemsCount, this._itemsCount)} selectedValuePath='value' displayMemberPath='text' selectedValue={this.itemsCount} itemsSource={this.Values.itemsCount} selectedIndexChanged={this._menuChanged.bind(this, MenuType.itemsCount)}>
</wjInput.Menu>
<wjInput.Menu header={'<b>Allow Add:</b> ' + this._getText(this.Values.yesNo, this.allowAdd)} selectedValuePath='value' displayMemberPath='text' selectedValue={this.allowAdd} itemsSource={this.Values.yesNo} selectedIndexChanged={this._menuChanged.bind(this, MenuType.allowAdd)}>
</wjInput.Menu>
<wjInput.Menu header={'<b>Selection:</b> ' + this.selectionMode} selectedValue={this.selectionMode} itemsSource={this.Values.selectionMode} selectedIndexChanged={this._menuChanged.bind(this, MenuType.selectionMode)}>
</wjInput.Menu>
<wjInput.Menu header={'<b>Headers Visibility:</b> ' + this.headersVisibility} selectedValue={this.headersVisibility} itemsSource={this.Values.headersVisibility} selectedIndexChanged={this._menuChanged.bind(this, MenuType.headersVisibility)}>
</wjInput.Menu>
<wjInput.Menu header={'<b>Show Selected Headers:</b> ' + this.showSelectedHeaders} selectedValue={this.showSelectedHeaders} itemsSource={this.Values.headersVisibility} selectedIndexChanged={this._menuChanged.bind(this, MenuType.showSelectedHeaders)}>
</wjInput.Menu>
<wjInput.Menu header={'<b>Show Marquee:</b> ' + this._getText(this.Values.yesNo, this.showMarquee)} selectedValuePath='value' displayMemberPath='text' selectedValue={this.showMarquee} itemsSource={this.Values.yesNo} selectedIndexChanged={this._menuChanged.bind(this, MenuType.showMarquee)}>
</wjInput.Menu>
<wjInput.Menu header={'<b>Data Maps:</b> ' + this._getText(this.Values.onOff, this.dataMaps)} selectedValuePath='value' displayMemberPath='text' selectedValue={this.dataMaps} itemsSource={this.Values.onOff} selectedIndexChanged={this._menuChanged.bind(this, MenuType.dataMaps)}>
</wjInput.Menu>
<wjInput.Menu header={'<b>Formatting:</b> ' + this._getText(this.Values.onOff, this.formatting)} selectedValuePath='value' displayMemberPath='text' selectedValue={this.formatting} itemsSource={this.Values.onOff} selectedIndexChanged={this._menuChanged.bind(this, MenuType.formatting)}>
</wjInput.Menu>
<br />
<br />
<button className='btn btn-default' onClick={this._toggleColumnVisibility.bind(this)}>
Show/Hide Column
</button>
<button className='btn btn-default' onClick={this._changeColumnSize.bind(this)}>
Resize Column
</button>
<button className='btn btn-default' onClick={this._toggleRowVisibility.bind(this)}>
Show/Hide Row
</button>
<button className='btn btn-default' onClick={this._changeRowSize.bind(this)}>
Resize Row
</button>
<button className='btn btn-default' onClick={this._changeDefaultRowSize.bind(this)}>
Default Row Size
</button>
<button className='btn btn-default' onClick={this._changeScrollPosition.bind(this)}>
Scroll Position
</button>
</div>
</div>
</div>;
}
//
// apply filter (applied on a 500 ms timeOut)
_applyFilter() {
if (this._toFilter) {
clearTimeout(this._toFilter);
}
//
this._toFilter = setTimeout(() => {
this._toFilter = null;
if (this._grid) {
let view = this._grid.collectionView;
if (view) {
if (!this.filter) {
view.filter = null;
}
else {
if (!view.filter) {
view.filter = this._filterFunction.bind(this);
}
else {
view.refresh();
}
}
}
}
}, 500);
}
//
// ICollectionView filter function
_filterFunction(item) {
let f = this.filter;
if (f && item) {
//
// split string into terms to enable multi-field searches such as 'us gadget red'
let terms = f.toUpperCase().split(' ');
//
// look for any term in any string field
for (let i = 0; i < terms.length; i++) {
let termFound = false;
for (let key in item) {
let value = item[key];
if (wijmo.isString(value) && value.toUpperCase().indexOf(terms[i]) > -1) {
termFound = true;
break;
}
}
//
// fail if any of the terms is not found
if (!termFound) {
return false;
}
}
}
//
// include item in view
return true;
}
//
_toggleColumnVisibility() {
let col = this._grid.columns[0];
col.visible = !col.visible;
}
//
_changeColumnSize() {
let col = this._grid.columns[0];
col.visible = true;
col.width = col.width < 0 ? 60 : -1;
col = this._grid.rowHeaders.columns[0];
col.width = col.width < 0 ? 40 : -1;
}
//
_toggleRowVisibility() {
let row = this._grid.rows[0];
row.visible = !row.visible;
}
//
_changeRowSize() {
let row = this._grid.rows[0];
row.visible = true;
row.height = row.height < 0 ? 80 : -1;
row = this._grid.columnHeaders.rows[0];
row.height = row.height < 0 ? 80 : -1;
}
//
_changeDefaultRowSize() {
this._grid.rows.defaultSize = this._grid.rows.defaultSize == 28 ? 65 : 28;
}
//
_changeScrollPosition() {
let flex = this._grid;
if (flex.scrollPosition.y == 0) {
let sz = flex.scrollSize;
flex.scrollPosition = new wijmo.Point(-sz.width / 2, -sz.height / 2);
}
else {
flex.scrollPosition = new wijmo.Point(0, 0);
}
}
//
_gridInitialized(sender) {
this._grid = sender;
this.setState({
selection: this._cellRangeToString(sender.selection)
});
}
//
_gridSelectionChanged(sender) {
this.setState({
selection: this._cellRangeToString(sender.selection)
});
}
//
_gridItemsSourceChanged(sender) {
// make columns 25% wider (for readability and to show how)
sender.columns.forEach((col) => col.width = col.renderSize * 1.25);
//
// update data maps and formatting
this._updateDataMapSettings();
//
// clear filter
// this.filter = '';
}
//
_filterChanged(e) {
this.filter = e.target.value;
}
//
_menuChanged(type, menu) {
if (menu.selectedIndex < 0) {
return;
}
//
switch (type) {
case MenuType.itemsCount:
this.itemsCount = menu.selectedValue;
break;
case MenuType.allowAdd:
this.allowAdd = menu.selectedValue;
break;
case MenuType.dataMaps:
this.dataMaps = menu.selectedValue;
break;
case MenuType.formatting:
this.formatting = menu.selectedValue;
break;
case MenuType.headersVisibility:
this.headersVisibility = menu.selectedValue;
break;
case MenuType.selectionMode:
this.selectionMode = menu.selectedValue;
break;
case MenuType.showMarquee:
this.showMarquee = menu.selectedValue;
break;
case MenuType.showSelectedHeaders:
this.showSelectedHeaders = menu.selectedValue;
break;
}
}
//
_getText(map, value) {
return map.filter(val => val.value === value)[0].text;
}
//
_cellRangeToString(value) {
let rng = '';
//
if (value instanceof grid.CellRange) {
rng = `(${value.row};${value.col})`;
if (!value.isSingleCell) {
rng += `-(${value.row2};${value.col2})`;
}
}
return rng;
}
//
// apply/remove data maps
_updateDataMaps() {
if (!this._grid) {
return;
}
//
let country = this._grid.columns.getColumn('countryId'), product = this._grid.columns.getColumn('productId'), color = this._grid.columns.getColumn('colorId');
//
if (country && product && color) {
if (this.dataMaps == true) {
country.showDropDown = true; // show drop-down for countries
product.showDropDown = false; // don't show it for products
color.showDropDown = false; // or colors (just to show how)
country.dataMap = this._buildDataMap(getCountries());
product.dataMap = this._buildDataMap(getProducts());
color.dataMap = this._buildDataMap(getColors());
}
else {
country.dataMap = null;
product.dataMap = null;
color.dataMap = null;
}
}
}
//
// build a data map from a string array using the indices as keys
_buildDataMap(items) {
let map = items.map((v, i) => ({ key: i, value: v }));
return new grid.DataMap(map, 'key', 'value');
}
//
// apply/remove column formatting
_updateFormatting() {
if (!this._grid) {
return;
}
//
let fmt = this.formatting;
this._setColumnFormat('amount', fmt ? 'c' : null);
this._setColumnFormat('amount2', fmt ? 'c' : null);
this._setColumnFormat('discount', fmt ? 'p0' : null);
this._setColumnFormat('start', fmt ? 'MMM d yy' : null);
this._setColumnFormat('end', fmt ? 'HH:mm' : null);
}
//
_setColumnFormat(name, format) {
let col = this._grid.columns.getColumn(name);
if (col) {
col.format = format;
}
}
//
_updateDataMapSettings() {
this._updateDataMaps();
this._updateFormatting();
}
}
//
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>GrapeCity Wijmo FlexGrid 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 id="app"></div>
</body>
</html>
.wj-flexgrid {
height: 400px;
margin: 6px 0;
}
.grid-sort-group .wj-menu,
.grid-sort-group .btn {
margin: 2px 2px 2px 0;
}
import { CollectionView } from '@grapecity/wijmo';
//
let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'];
let products = ['Widget', 'Gadget', 'Doohickey'];
let colors = ['Black', 'White', 'Red', 'Green', 'Blue'];
//
// generate some random data
export function getData(count, currentChangedHdl) {
let data = [];
let dt = new Date();
//
// add count items
for (let i = 0; i < count; i++) {
// constants used to create data items
let date = new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60), countryId = Math.floor(Math.random() * countries.length), productId = Math.floor(Math.random() * products.length), colorId = Math.floor(Math.random() * colors.length);
//
// add the item to the list
data.push({
id: i,
start: date,
end: date,
country: countries[countryId],
product: products[productId],
color: colors[colorId],
countryId: countryId,
productId: productId,
colorId: colorId,
amount: Math.random() * 10000 - 5000,
amount2: Math.random() * 10000 - 5000,
discount: Math.random() / 4,
active: i % 4 == 0
});
}
//
// return a CollectionView so multiple controls bound to this source
// will be updated automatically (TFS 145538)
let cv = new CollectionView(data);
if (currentChangedHdl) {
cv.currentChanged.addHandler(currentChangedHdl);
}
//
return cv;
}
//
// get possible values for each field
export function getCountries() {
return countries;
}
//
export function getProducts() {
return products;
}
//
export function getColors() {
return colors;
}
import 'bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
import './app.css';
//
import * as React from 'react';
//
// CollectionView navigator component
export class Navigator extends React.Component {
//
constructor(props) {
super(props);
this.BtnFirstStyle = { marginRight: '-4px' };
this.BtnLastStyle = { marginLeft: '-4px' };
}
//
moveCurrentToFirst() {
this.props.view.moveCurrentToFirst();
this.forceUpdate();
}
//
moveCurrentToPrevious() {
this.props.view.moveCurrentToPrevious();
this.forceUpdate();
}
//
moveCurrentToNext() {
this.props.view.moveCurrentToNext();
this.forceUpdate();
}
//
moveCurrentToLast() {
this.props.view.moveCurrentToLast();
this.forceUpdate();
}
//
render() {
return <div className='wj-control wj-content wj-pager'>
<div className='wj-input-group'>
<span className='wj-input-group-btn'>
<button type='button' className='wj-btn wj-btn-default' onClick={this.moveCurrentToFirst.bind(this)} disabled={this.props.view.currentPosition <= 0}>
<span className='wj-glyph-left' style={this.BtnFirstStyle}></span>
<span className='wj-glyph-left'></span>
</button>
</span>
<span className='wj-input-group-btn'>
<button type='button' className='wj-btn wj-btn-default' onClick={this.moveCurrentToPrevious.bind(this)} disabled={this.props.view.currentPosition <= 0}>
<span className='wj-glyph-left'></span>
</button>
</span>
<input type='text' className='wj-form-control' value={this.props.view.currentPosition + 1 + ' / ' + this.props.view.itemCount} disabled/>
<span className='wj-input-group-btn'>
<button type='button' className='wj-btn wj-btn-default' onClick={this.moveCurrentToNext.bind(this)} disabled={this.props.view.currentPosition >= this.props.view.itemCount - 1}>
<span className='wj-glyph-right'></span>
</button>
</span>
<span className='wj-input-group-btn'>
<button type='button' className='wj-btn wj-btn-default' onClick={this.moveCurrentToLast.bind(this)} disabled={this.props.view.currentPosition >= this.props.view.itemCount - 1}>
<span className='wj-glyph-right'></span>
<span className='wj-glyph-right' style={this.BtnLastStyle}></span>
</button>
</span>
</div>
</div>;
}
}