FlexGrid Multi-Column Sort

The FlexGrid's UI only allows sorting one column at a time (by clicking the column headers). This sample shows you can add a UI for sorting on multiple columns. It uses the grid's sortingColumn event to add properties to the sortDescriptions property of the grid's collectionView. Click any column header to add or flip the sort for that column. Use ctrl+click to clear all sorts and start over.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjGrid from '@grapecity/wijmo.grid'; import * as wjCore from '@grapecity/wijmo'; import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // // create the grid var theGrid = new wjGrid.FlexGrid('#theGrid', { itemsSource: getData(200) }); // // listen for clicks on column headers theGrid.sortingColumn.addHandler(function (s, e) { var view = s.collectionView, sds = view.sortDescriptions; // // prevent default behavior e.cancel = true; // // if the control key is pressed, clear all sorts if (e.data.ctrlKey) { sds.clear(); return; } // // flip direction or add new sort var prop = s.columns[e.col].binding, index = -1; for (var i = 0; i < sds.length && index < 0; i++) { if (sds[i].property == prop) { index = i; } } if (index < 0) { // not found, add now var sd = new wjCore.SortDescription(prop, true); sds.push(sd); } else { // found, flip its direction var sd = new wjCore.SortDescription(prop, !sds[index].ascending); sds.splice(index, 1, sd); } }); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexGrid Multi-column Sorting</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <div id="theGrid"></div> </div> </body> </html> // create some random data export function getData(cnt) { var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), data = []; for (var i = 0; i < cnt; i++) { data.push({ id: i, country: countries[i % countries.length], active: i % 5 != 0, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }); } return data; } .wj-flexgrid { max-height: 250px; margin-bottom: 12px; } .header { display: inline-block; width: 150px; text-align: right; font-weight: normal; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import { Component, enableProdMode, NgModule, Inject } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import * as wjcCore from '@grapecity/wijmo'; import * as wjcGrid from '@grapecity/wijmo.grid'; import { WjGridModule } from '@grapecity/wijmo.angular2.grid'; import { DataService } from './app.data'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { data: any[]; constructor(@Inject(DataService) dataSvc: DataService) { this.data = dataSvc.getData(200); } initializeGrid(flex: wjcGrid.FlexGrid) { // listen for clicks on column headers flex.sortingColumn.addHandler((s: wjcGrid.FlexGrid, e: wjcGrid.CellRangeEventArgs) => { let view = s.collectionView, sds = view.sortDescriptions; // prevent default behavior e.cancel = true; // if the control key is pressed, clear all sorts if (e.data.ctrlKey) { sds.clear(); return; } // flip direction or add new sort let prop = s.columns[e.col].binding, index = -1; for (let i = 0; i < sds.length && index < 0; i++) { if (sds[i].property == prop) { index = i; } } let sd: wjcCore.SortDescription; if (index < 0) { // not found, add now sd = new wjcCore.SortDescription(prop, true); sds.push(sd); } else { // found, flip its direction sd = new wjcCore.SortDescription(prop, !sds[index].ascending); sds.splice(index, 1, sd); } }); } } @NgModule({ imports: [WjGridModule, BrowserModule], providers: [DataService], 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 Multi-column Sorting</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"> <wj-flex-grid #flex (initialized)="initializeGrid(flex)" [(itemsSource)]="data"> </wj-flex-grid> </div> import { Injectable } from '@angular/core'; @Injectable() export class DataService { getData(cnt: number): any[] { let countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), data = []; for (let i = 0; i < cnt; i++) { data.push({ id: i, country: countries[i % countries.length], active: i % 5 != 0, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }); } return data; } } .wj-flexgrid { max-height: 250px; margin-bottom: 12px; } .header { display: inline-block; width: 150px; text-align: right; font-weight: normal; } <template> <div class="container-fluid"> <wj-flex-grid :initialized="initializeGrid" :itemsSource="data"> </wj-flex-grid> </div> </template> <script> import "@grapecity/wijmo.styles/wijmo.css"; import 'bootstrap.css'; import Vue from 'vue'; import '@grapecity/wijmo.vue2.core'; import '@grapecity/wijmo.vue2.grid'; import * as wjcCore from '@grapecity/wijmo'; import { getData } from './data'; let App = Vue.extend({ name: 'app', data: function(){ return { data: getData(200) } }, methods: { initializeGrid(flex) { // listen for clicks on column headers flex.sortingColumn.addHandler((s, e) => { let view = s.collectionView, sds = view.sortDescriptions; // prevent default behavior e.cancel = true; // if the control key is pressed, clear all sorts if (e.data.ctrlKey) { sds.clear(); return; } // flip direction or add new sort let prop = s.columns[e.col].binding, index = -1; for (let i = 0; i < sds.length && index < 0; i++) { if (sds[i].property == prop) { index = i; } } let sd; if (index < 0) { // not found, add now sd = new wjcCore.SortDescription(prop, true); sds.push(sd); } else { // found, flip its direction sd = new wjcCore.SortDescription(prop, !sds[index].ascending); sds.splice(index, 1, sd); } }); } } }); new Vue({ render: h => h(App) }).$mount('#app'); </script> <style> .wj-flexgrid { max-height: 250px; margin-bottom: 12px; } .header { display: inline-block; width: 150px; text-align: right; font-weight: normal; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>AutoComplete</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> // create some random data export function getData(cnt) { var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), data = []; for (var i = 0; i < cnt; i++) { data.push({ id: i, country: countries[i % countries.length], active: i % 5 != 0, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }); } return data; } import "@grapecity/wijmo.styles/wijmo.css"; import "bootstrap.css"; import "./app.css"; // import * as React from 'react'; import * as ReactDOM from 'react-dom'; // import * as wjcCore from "@grapecity/wijmo"; import * as wjcGrid from "@grapecity/wijmo.react.grid"; import { getData } from "./data"; class App extends React.Component { constructor(props) { super(props); this.state = { data: getData(200) }; } render() { return <div className="container-fluid"> <wjcGrid.FlexGrid initialized={this.initializeGrid.bind(this)} itemsSource={this.state.data}></wjcGrid.FlexGrid> </div>; } initializeGrid(flex) { // listen for clicks on column headers flex.sortingColumn.addHandler((s, e) => { let view = s.collectionView, sds = view.sortDescriptions; // prevent default behavior e.cancel = true; // if the control key is pressed, clear all sorts if (e.data.ctrlKey) { sds.clear(); return; } // flip direction or add new sort let prop = s.columns[e.col].binding, index = -1; for (let i = 0; i < sds.length && index < 0; i++) { if (sds[i].property == prop) { index = i; } } let sd; if (index < 0) { // not found, add now sd = new wjcCore.SortDescription(prop, true); sds.push(sd); } else { // found, flip its direction sd = new wjcCore.SortDescription(prop, !sds[index].ascending); sds.splice(index, 1, sd); } }); } } 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 OLAP Pivot Chart 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 { max-height: 250px; margin-bottom: 12px; } .header { display: inline-block; width: 150px; text-align: right; font-weight: normal; } // create some random data export function getData(cnt) { var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), data = []; for (var i = 0; i < cnt; i++) { data.push({ id: i, country: countries[i % countries.length], active: i % 5 != 0, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }); } return data; }