The information for rowFilter and the checked state on the filter dialog of SheetTable are synchronized with the filter result of Slicers attached with TableSlicerData. All of the slicers (attached with TableSlicerData) receive the onFilter notice and get the filtered result after the SheetTable filters completely with code or the filter dialog.
You can use TableSlicerData as follows:
import { Component, NgModule, enableProdMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { SpreadSheetsModule } from '@mescius/spread-sheets-angular';
import GC from '@mescius/spread-sheets';
import "@mescius/spread-sheets-shapes";
import "@mescius/spread-sheets-slicers";
import './styles.css';
class CustomSlicer {
container: HTMLElement;
slicerData: any;
columnName: string;
name: string;
constructor(container: HTMLElement, name: string) {
this.container = container;
this.name = name;
this.slicerData = null;
this.columnName = null;
}
setData(slicerData: any[], columnName: string) {
this.slicerData = slicerData;
this.columnName = columnName;
this.slicerData.attachListener(this);
this.onDataLoaded();
}
onDataLoaded() {
let columnName = this.columnName,
exclusiveData = this.slicerData.getExclusiveData(columnName);
// Create slicer dom tree.
let strong = document.createElement('strong');
strong.innerText = this.name + ':';
let br = document.createElement('br');
this.container.appendChild(strong);
this.container.appendChild(br);
let domString = "",
id;
let div = document.createElement('div');
div.setAttribute('class', 'option-group')
for (let i = 0; i < exclusiveData.length; i++) {
id = columnName + (i + 1);
domString += '<input type="checkbox" name="' + columnName + '" value="' + exclusiveData[i] + '" id="' + id + '" checked>';
domString += '<label for="' + id + '">' + exclusiveData[i] + '</label></br>';
}
div.innerHTML = domString;
this.container.appendChild(div);
// Attach events to dom element.
let self = this;
document.querySelector('.options-container').addEventListener('change', function(e) {
// Invoke getExclusiveData method to get exclusive data from slicerData.
let exclusiveData = self.slicerData.getExclusiveData(self.columnName);
// parent = this.parentNode.parentNode;
let items = document.querySelectorAll('.options-container input');
let indexes = [];
for (let i = 0, length = items.length; i < length; i++) {
if ((<HTMLInputElement>items[i]).checked) {
let value: any = (<HTMLInputElement>items[i]).value;
if (!isNaN(parseInt(value))) {
value = parseInt(value + '');
}
if (exclusiveData.indexOf(value) != -1) {
indexes.push(exclusiveData.indexOf(value))
}
}
}
if (indexes.length === 0) {
// Invoke doUnfilter method when all item are not selected.
self.slicerData.doUnfilter(self.columnName);
} else {
// Invoke doFilter method when any item is selected.
self.slicerData.doFilter(self.columnName, {
exclusiveRowIndexes: indexes
});
}
});
}
}
@Component({
selector: 'app-component',
templateUrl: 'src/app.component.html'
})
export class AppComponent {
spread: GC.Spread.Sheets.Workbook = null;
hostStyle = {
width: 'calc(100% - 280px)',
height: '100%',
overflow: 'hidden',
float: 'left'
};
initSpread($event: any) {
let spread = $event.spread;
let sheet = spread.getActiveSheet();
// Define data source.
let columnNames = ["Name", "Sex", "City", "Birthday"],
data = [
["Bob", "Man", "NewYork", "1968/06/08"],
["Betty", "Woman", "Washington", "1972/07/03"],
["Alice", "Woman", "Atlanta", "1964/03/02"],
["Tom", "Man", "Houston", "1986/12/03"],
["Jenny", "Woman", "Washington", "1956/10/13"],
["Nacy", "Woman", "NewYork", "1989/01/14"],
["John", "Man", "Houston", "1995/01/01"],
["Mark", "Man", "Atlanta", "1965/11/11"],
["Susan", "Woman", "Atlanta", "1983/07/08"]
];
// Create a table.
let table = sheet.tables.addFromDataSource("table1", 1, 1, data);
table.setColumnName(0, columnNames[0]);
table.setColumnName(1, columnNames[1]);
table.setColumnName(2, columnNames[2]);
table.setColumnName(3, columnNames[3]);
sheet.getRange(-1, 1, -1, 6).width(80);
// Get TableSlicerData from table.
let slicerData = table.getSlicerData();
// Create a custom slicer and add it to dom tree.
let slicer1 = new CustomSlicer(document.getElementById("cityContainer"), 'City');
slicer1.setData(slicerData, "City");
let slicer2 = new CustomSlicer(document.getElementById("sexContainer"), 'Sex');
slicer2.setData(slicerData, "Sex");
}
bindSlicerEvent(spread: GC.Spread.Sheets.Workbook) {
let self = this;
spread.bind(GC.Spread.Sheets.Events.SlicerChanged, function(event: any, args: any) {
var sheet = args.sheet;
var slicer = args.slicer;
if (!slicer) {
return;
}
var propertyName = args.propertyName;
if (propertyName === "isSelected") {
if (slicer.isSelected()) {
self.initSlicerSetting(sheet, slicer);
self.selectedSlicersList = getSelectedSlicers(sheet)
self.disableForm = false;
} else {
self.disableForm = true;
}
}
});
}
initSlicerSetting(sheet: GC.Spread.Sheets.Worksheet, slicer: GC.Spread.Sheets.Slicers.Slicer) {
this.sortState = slicer.sortState();
this.protectSheet = sheet.isProtected;
this.lockSlicer = slicer.isLocked();
this.fixedPosition = slicer.fixedPosition();
this.dynamicMove = slicer.dynamicMove();
this.dynamicSize = slicer.dynamicSize();
}
}
@NgModule({
imports: [BrowserModule, SpreadSheetsModule, FormsModule],
declarations: [AppComponent],
exports: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
enableProdMode();
// Bootstrap application with hash style navigation and global services.
platformBrowserDynamic().bootstrapModule(AppModule);
<!doctype html>
<html style="height:100%;font-size:14px;">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/angular/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<!-- Polyfills -->
<script src="$DEMOROOT$/en/angular/node_modules/core-js/client/shim.min.js"></script>
<script src="$DEMOROOT$/en/angular/node_modules/zone.js/fesm2015/zone.min.js"></script>
<!-- SystemJS -->
<script src="$DEMOROOT$/en/angular/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.import('@angular/compiler');
System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators));
System.import('$DEMOROOT$/en/lib/angular/license.ts');
System.import('./src/app.component');
});
</script>
</head>
<body>
<app-component></app-component>
</body>
</html>
<div class="sample-tutorial">
<gc-spread-sheets [hostStyle]="hostStyle" (workbookInitialized)="initSpread($event)">
</gc-spread-sheets>
<div class="options-container">
<div id="cityContainer" class="sample-group"></div>
<div id="sexContainer" class="sample-group"></div>
</div>
</div>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: calc(100% - 280px);
height: 100%;
overflow: auto;
float: left;
}
.options-container {
float: right;
width: 280px;
padding: 12px;
height: 100%;
box-sizing: border-box;
background: #fbfbfb;
overflow: auto;
}
label {
display: inline-block;
margin: 6px 0;
}
strong {
display: inline-block;
margin: 12px 0;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
(function (global) {
System.config({
transpiler: 'ts',
typescriptOptions: {
tsconfig: true
},
meta: {
'typescript': {
"exports": "ts"
},
'*.css': { loader: 'css' }
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
'core-js': 'npm:core-js/client/shim.min.js',
'zone': 'npm:zone.js/fesm2015/zone.min.js',
'rxjs': 'npm:rxjs/dist/bundles/rxjs.umd.min.js',
'@angular/core': 'npm:@angular/core/fesm2022',
'@angular/common': 'npm:@angular/common/fesm2022/common.mjs',
'@angular/compiler': 'npm:@angular/compiler/fesm2022/compiler.mjs',
'@angular/platform-browser': 'npm:@angular/platform-browser/fesm2022/platform-browser.mjs',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/fesm2022/platform-browser-dynamic.mjs',
'@angular/common/http': 'npm:@angular/common/fesm2022/http.mjs',
'@angular/router': 'npm:@angular/router/fesm2022/router.mjs',
'@angular/forms': 'npm:@angular/forms/fesm2022/forms.mjs',
'jszip': 'npm:jszip/dist/jszip.min.js',
'typescript': 'npm:typescript/lib/typescript.js',
'ts': './plugin.js',
'tslib':'npm:tslib/tslib.js',
'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',
'@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js',
'@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js',
'@mescius/spread-sheets-slicers': 'npm:@mescius/spread-sheets-slicers/index.js',
'@mescius/spread-sheets-angular': 'npm:@mescius/spread-sheets-angular/fesm2020/mescius-spread-sheets-angular.mjs',
'@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
src: {
defaultExtension: 'ts'
},
rxjs: {
defaultExtension: 'js'
},
"node_modules": {
defaultExtension: 'js'
},
"node_modules/@angular": {
defaultExtension: 'mjs'
},
"@mescius/spread-sheets-angular": {
defaultExtension: 'mjs'
},
'@angular/core': {
defaultExtension: 'mjs',
main: 'core.mjs'
}
}
});
})(this);