import { Injectable } from '@angular/core';
// Common data service
@Injectable()
export class DataSvc {
private _products = ['Widget', 'Gadget', 'Doohickey'];
private _countries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'];
get products(): string[] {
return this._products;
}
get countries(): string[] {
return this._countries;
}
// get matches for a search term
getData(count: number): any[] {
var data = [],
i = 0,
countryId,
productId;
for (var i = 0; i < count; i++) {
countryId = Math.floor(Math.random() * this._countries.length);
productId = Math.floor(Math.random() * this._products.length);
data.push({
id: i,
countryId: countryId,
productId: productId,
date: new Date(2014, i % 12, i % 28),
amount: Math.random() * 10000,
active: i % 4 === 0
});
}
return data;
}
}
---------------------Component-------------------
// Angular
import * as wjcGridSheet from 'wijmo/wijmo.grid.sheet';
import * as wjcInput from 'wijmo/wijmo.input';
import * as wjcGrid from 'wijmo/wijmo.grid';
import * as wjcCore from 'wijmo/wijmo';
import { Component, EventEmitter, Inject, enableProdMode, ViewChild, NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { WjGridSheetModule } from 'wijmo/wijmo.angular2.grid.sheet';
import { WjInputModule } from 'wijmo/wijmo.angular2.input';
import { TabsModule } from './components/AppTab';
import { DataSvc } from './services/DataSvc';
'use strict';
// The Explorer application root component.
@Component({
selector: 'app-cmp',
templateUrl: 'src/app.html'
})
export class AppCmp {
protected dataSvc: DataSvc;
data: any[];
// references FlexSheet named 'flexSheet' in the view
@ViewChild('flexSheetIntro') flexSheetIntro: wjcGridSheet.FlexSheet;
constructor(@Inject(DataSvc) dataSvc: DataSvc) {
this.dataSvc = dataSvc;
this.data = dataSvc.getData(50);
}
flexSheetInit(flexSheetIntro: wjcGridSheet.FlexSheet) {
var self = this;
if (flexSheetIntro) {
flexSheetIntro.deferUpdate(() => {
flexSheetIntro.selectedSheetIndex = 0;
flexSheetIntro.selectedSheet.itemsSource = this.data;
self._initDataMapForBindingSheet(flexSheetIntro);
});
}
}
// initialize the dataMap for the bound sheet.
private _initDataMapForBindingSheet(flexSheet) {
var column;
if (flexSheet) {
column = flexSheet.columns.getColumn('countryId');
if (column && !column.dataMap) {
column.dataMap = this._buildDataMap(this.dataSvc.countries);
}
column = flexSheet.columns.getColumn('productId');
if (column && !column.dataMap) {
column.dataMap = this._buildDataMap(this.dataSvc.products);
}
}
}
// build a data map from a string array using the indices as keys
private _buildDataMap(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');
}
}
@NgModule({
imports: [WjInputModule, WjGridSheetModule, BrowserModule, FormsModule, TabsModule],
declarations: [AppCmp],
providers: [DataSvc],
bootstrap: [AppCmp]
})
export class AppModule {
}
enableProdMode();
// Bootstrap application with hash style navigation and global services.
platformBrowserDynamic().bootstrapModule(AppModule);
/* set default grid height and some shadow */
.wj-flexsheet {
height: 400px;
background-color: white;
box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75);
margin-bottom: 12px;
}
Result (live):
Sorting
FlexSheet can be sorted by any of its columns.
The SortManager helps FlexSheet to manage the sort process. The following example uses SortManager to specify the order of the sorting, add or remove sort columns, and change the order of the sort columns.
// references FlexSheet named 'sortSheet' in the view
@ViewChild('sortSheet') sortSheet: wjcGridSheet.FlexSheet;
sortSheetInit(sortSheet: wjcGridSheet.FlexSheet) {
var self = this;
if (sortSheet) {
sortSheet.deferUpdate(() => {
sortSheet.selectedSheetIndex = 0;
sortSheet.selectedSheet.itemsSource = this.data;
self._initDataMapForBindingSheet(sortSheet);
self.sortManager = sortSheet.sortManager;
self.columns = self._getColumns(sortSheet);
});
sortSheet.selectedSheetChanged.addHandler(() => {
self.columns = self._getColumns(sortSheet);
if (!self.sortManager) {
self.sortManager = sortSheet.sortManager;
}
});
}
}
// commit the sorts
commitSort() {
this.sortManager.commitSort();
};
// cancel the sorts
cancelSort() {
this.sortManager.cancelSort();
};
// add new sort level
addSortLevel() {
this.sortManager.addSortLevel();
};
// delete current sort level
deleteSortLevel() {
this.sortManager.deleteSortLevel();
};
// copy a new sort level by current sort level setting.
copySortLevel() {
this.sortManager.copySortLevel();
};
// move the sort level
moveSortLevel(offset) {
this.sortManager.moveSortLevel(offset);
};
// apply column index property for sort item
applySortColumnIndex(e, sortItem) {
sortItem.columnIndex = +e.target.value;
}
// apply asceding property for sort item
applySortAscending(e, sortItem) {
if (e.target.value === 'true') {
sortItem.ascending = true;
} else {
sortItem.ascending = false;
}
}
private _getColumns(flexSheet: wjcGridSheet.FlexSheet): string[] {
var columns = [],
i = 0;
if (flexSheet) {
for (; i < flexSheet.columns.length; i++) {
columns.push('Column ' + wjcGridSheet.FlexSheet.convertNumberToAlpha(i));
}
}
return columns;
}
Result (live):
Column
Order
Format Cells
FlexSheet allows you to set format for each cell. This includes setting font style, data format of cell value (Date/Number format), cell's fill color and horizontal alignment.
FlexSheet supports merging the selected cells into one by invoking the mergeRange method.
If the selected cells contain merged cell, the mergeRange method will un-merge the merged cell. Otherwise, it will merge the selected cells into one cell.
FlexSheet allows merging of cells that contain any data. This is different from FlexGrid, which supports content-driven cell merging.
// references FlexSheet named 'mergeCellSheet' in the view
@ViewChild('mergeCellSheet') mergeCellSheet: wjcGridSheet.FlexSheet;
mergeCellSheetInit(mergeCellSheet: wjcGridSheet.FlexSheet) {
var self = this;
if (mergeCellSheet) {
mergeCellSheet.selectionChanged.addHandler(function () {
self.mergeState = mergeCellSheet.getSelectionFormatState();
});
}
}
mergeCells() {
if (this.mergeCellSheet) {
this.mergeCellSheet.mergeRange();
this.mergeState = this.mergeCellSheet.getSelectionFormatState();
}
}
Result (live):
Drag & Drop
FlexSheet supports dragging and dropping the columns or rows into other columns or rows.
FlexSheet not only copies or moves the data of the cells, but also copies or moves the style of the cells.
When you drag and drop columns/rows without pressing any key, it will move the selected columns or rows into the target columns or rows.
When you drag and drop columns/rows with 'Ctrl' key pressed, it will copy the selected columns or rows into the target columns or rows.
When you drag and drop columns/rows with 'Shift' key pressed, it will change the position of the selected columns or rows with the target columns or rows.
Although the functions provided in FlexSheet should cover a vast majority of use scenarios, still there may be some cases where users may need additional functions.
FlexSheet provides two methods that allow you to add your own custom functions: addCustomFunction and unknownFunction.
The addCustomFunction method adds a custom function to the list of built-in functions.
The addCustomFunction method is usually the best way to add custom functions to the FlexSheet calculation engine. However, there are scenarios where the function names are variable or unknown ahead of time. For example, named ranges or value dictionaries.
In these situations, you can use the unknownFunction event to look up the value of a function dynamically. When the FlexSheet detects an unknown function name, it raises the unknownFunction event and provides parameters that contain the function name and parameters. The event handler then calculates the result and returns the value.