Accessibility Extender

The FlexGrid has extensive built-in accessibility support. But there are situations where you may want to extend that and provide additional support that is specific to your application or user base. This sample has an AccessibilityExtender class that shows how to add your own app-specific accessibility features.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjGrid from '@grapecity/wijmo.grid'; import { AccessibilityExtender } from './accessibility-extender'; document.readyState === 'complete' ? init() : window.onload = init; function init() { // create the grid var theGrid = new wjGrid.FlexGrid('#theGrid', { itemsSource: getData(100), alternatingRowStep: 0, selectionMode: 'ListBox' }); // extend accessibility features var acX = new AccessibilityExtender(theGrid); // notify users when columns are sorted theGrid.sortedColumn.addHandler(function (s, e) { let col = s.columns[e.col]; acX.alert('column ' + col.header + ' sorted in ' + (col.currentSort == '+' ? 'ascending' : 'descending') + ' order'); }); // hook up filter var toSearch = null; document.getElementById('filter').addEventListener('input', function (e) { clearTimeout(toSearch); toSearch = setTimeout(function () { var search = e.target.value, rx = new RegExp(search, 'i'); theGrid.collectionView.filter = function (item) { return !search || JSON.stringify(item).match(rx) != null; }; // notify users that a filter was applied setTimeout(function () { var msg = search ? 'grid filtered on ' + search : 'filter removed'; msg += ': ' + theGrid.rows.length + ' items displayed'; acX.alert(msg); }, 200); }, 900); }); // get some random data function getData(count) { var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), products = 'Tents,Boots,Knives,Bows,Arrows,Sleeping Bags,Lamps'.split(','), data = []; for (var i = 0; i < count; i++) { data.push({ id: i, country: countries[i % countries.length], product: products[i % products.length], active: i % 5 != 0, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }); } return data; } } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexGrid Accessibility Extender</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 class="input-group"> <div class="input-group-addon"> <span class="glyphicon glyphicon-search"></span> </div> <input type="text" class="form-control" id="filter" placeholder="filter"> </div> <div id="theGrid"></div> </div> </body> </html> .wj-flexgrid { height: 300px; margin: 6px 0; } .wj-cell { border-right: none; padding: 8px 3px; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import { Component, enableProdMode, NgModule, ViewChild } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { WjGridModule } from '@grapecity/wijmo.angular2.grid'; import * as wjcGrid from '@grapecity/wijmo.grid'; import { AccessibilityExtender } from './app.accessibility-extender'; @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { data: any[]; private _acX: AccessibilityExtender; private _toSearch: number; // DataSvc will be passed by derived classes constructor() { this.data = this._getData(100); } @ViewChild('flex') flex: wjcGrid.FlexGrid; ngAfterViewInit() { this._acX = new AccessibilityExtender(this.flex); document.querySelector('#filter').addEventListener('input', (e: any) => { clearTimeout(this._toSearch); this._toSearch = setTimeout(() => { let search = (<HTMLInputElement>e.target).value, rx = new RegExp(search, 'i'); this.flex.collectionView.filter = (item: any) => { return !search || JSON.stringify(item).match(rx) != null; } // notify users that a filter was applied setTimeout(() => { let msg = search ? 'grid filtered on ' + search : 'filter removed'; msg += ': ' + this.flex.rows.length + ' items displayed'; this._acX.alert(msg); }, 200); }, 900); }); } initializeGrid(flex: wjcGrid.FlexGrid) { // notify users when columns are sorted flex.sortedColumn.addHandler((s: wjcGrid.FlexGrid, e: wjcGrid.CellRangeEventArgs) => { let col = s.columns[e.col]; this._acX.alert('column ' + col.header + ' sorted in ' + (col.currentSort == '+' ? 'ascending' : 'descending') + ' order'); }); } private _getData(count: number) { // create some random data let countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), products = 'Tents,Boots,Knives,Bows,Arrows,Sleeping Bags,Lamps'.split(','), data = []; for (let i = 0; i < count; i++) { data.push({ id: i, country: countries[i % countries.length], product: products[i % products.length], active: i % 5 != 0, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }); } return data; } } @NgModule({ imports: [WjGridModule, BrowserModule], declarations: [AppComponent], 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 Accessibility Extender</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"> <div class="input-group"> <div class="input-group-addon"> <span class="glyphicon glyphicon-search"></span> </div> <input type="text" class="form-control" id="filter" placeholder="filter"> </div> <!-- the grid --> <wj-flex-grid #flex [alternatingRowStep]="0" [selectionMode]="'ListBox'" [(itemsSource)]="data" (initialized)="initializeGrid(flex)"> </wj-flex-grid> </div> .wj-flexgrid { height: 300px; margin: 6px 0; } .wj-cell { border-right: none; padding: 8px 3px; } <template> <div class="container-fluid"> <div class="input-group"> <div class="input-group-addon"> <span class="glyphicon glyphicon-search"></span> </div> <input type="text" class="form-control" id="filter" placeholder="filter"> </div> <!-- the grid --> <wj-flex-grid id="sample-grid" :alternatingRowStep="0" selectionMode="ListBox" :itemsSource="data" :initialized="initializeGrid"> </wj-flex-grid> </div> </template> <script> import '@grapecity/wijmo.styles/wijmo.css'; import 'bootstrap.css'; import Vue from 'vue'; import * as wijmo from '@grapecity/wijmo'; import * as gridPdf from '@grapecity/wijmo.grid.pdf'; import { WjGridModule } from '@grapecity/wijmo.vue2.grid'; import * as wjcGrid from '@grapecity/wijmo.grid'; import { AccessibilityExtender } from './accessibility-extender'; new Vue({ el: '#app', data: { data: null, _acX: null }, methods: { initializeGrid(ctl) { this.flex = ctl; this.data = this._getData(100); this.flex.sortedColumn.addHandler((s, e) => { let col = s.columns[e.col]; this._acX.alert('column ' + col.header + ' sorted in ' + (col.currentSort == '+' ? 'ascending' : 'descending') + ' order'); }); }, _getData(count) { // create some random data let countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), products = 'Tents,Boots,Knives,Bows,Arrows,Sleeping Bags,Lamps'.split(','), data = []; for (let i = 0; i < count; i++) { data.push({ id: i, country: countries[i % countries.length], product: products[i % products.length], active: i % 5 != 0, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }); } return data; } }, mounted: function(){ this._acX = new AccessibilityExtender(this.flex); document.querySelector('#filter').addEventListener('input', (e) => { clearTimeout(this._toSearch); this._toSearch = setTimeout(() => { let search = e.target.value, rx = new RegExp(search, 'i'); this.flex.collectionView.filter = (item) => { return !search || JSON.stringify(item).match(rx) != null; } // notify users that a filter was applied setTimeout(() => { let msg = search ? 'grid filtered on ' + search : 'filter removed'; msg += ': ' + this.flex.rows.length + ' items displayed'; this._acX.alert(msg); }, 200); }, 900); }); } }); </script> <style> .wj-flexgrid { height: 300px; margin: 6px 0; } #sample-grid .wj-cell { border-right: none; padding: 8px 3px; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexGrid Accessibility Extender</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> 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 wjGrid from '@grapecity/wijmo.react.grid'; import { AccessibilityExtender } from './accessibility-extender'; class App extends React.Component { constructor(props) { super(props); this.state = { data: null }; } render() { return <div className="container-fluid"> <div className="input-group"> <div className="input-group-addon"> <span className="glyphicon glyphicon-search"></span> </div> <input type="text" className="form-control" id="filter" placeholder="filter"> </input> </div> <wjGrid.FlexGrid alternatingRowStep={0} selectionMode="ListBox" itemsSource={this.state.data} initialized={this.initializeGrid.bind(this)}> </wjGrid.FlexGrid> </div>; } initializeGrid(ctl) { this._flex = ctl; this._flex.sortedColumn.addHandler((s, e) => { var col = s.columns[e.col]; this._acX.alert('column ' + col.header + ' sorted in ' + (col.currentSort == '+' ? 'ascending' : 'descending') + ' order'); }); this.setState({ data: this.getData(100) }); } getData(count) { // create some random data let countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), products = 'Tents,Boots,Knives,Bows,Arrows,Sleeping Bags,Lamps'.split(','), data = []; for (let i = 0; i < count; i++) { data.push({ id: i, country: countries[i % countries.length], product: products[i % products.length], active: i % 5 != 0, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }); } return data; } componentDidMount() { this._acX = new AccessibilityExtender(this._flex); document.querySelector('#filter').addEventListener('input', (e) => { clearTimeout(this._toSearch); this._toSearch = setTimeout(() => { let target = e.target; let search = target.value, rx = new RegExp(search, 'i'); this._flex.collectionView.filter = (item) => { return !search || JSON.stringify(item).match(rx) != null; }; // notify users that a filter was applied setTimeout(() => { let msg = search ? 'grid filtered on ' + search : 'filter removed'; msg += ': ' + this._flex.rows.length + ' items displayed'; this._acX.alert(msg); }, 200); }, 900); }); } } 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 Accessibility Extender</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: 300px; margin: 6px 0; } .wj-cell { border-right: none; padding: 8px 3px; }