Sorting (Angular)

The FlexGrid control supports sorting via the source CollectionView. By default, clicking on any column header will sort the data based on the column that was clicked.

Clicking the same column header again will revert the sort order. Control-clicking the column header will remove the sort.

You may customize the sorting behavior using the grid's showSort and allowSorting properties.

Learn about FlexGrid | FlexGrid API Reference

This example uses Angular.

app.component.ts
index.html
app.component.html
styles.css
Copy to CodeMine
import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import './styles.css'; // import '@angular/compiler'; import { Component, ElementRef, enableProdMode, ViewChild, ɵresolveComponentResources } from '@angular/core'; import { BrowserModule, bootstrapApplication } from '@angular/platform-browser'; import * as wjGrid from '@mescius/wijmo.grid'; import { WjGridModule } from '@mescius/wijmo.angular2.grid'; // @Component({ standalone: true, imports: [WjGridModule, BrowserModule], selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { data: any[]; // references FlexGrid named 'flex' in the view @ViewChild('flex', { static: true }) flex: wjGrid.FlexGrid; @ViewChild('cboFlexGridSortOrder', { static: true }) cboFlexGridSortOrder: ElementRef; @ViewChild('cboColumns', { static: true }) cboColumns: ElementRef; @ViewChild('cboColumnSortOrder', { static: true }) cboColumnSortOrder: ElementRef; @ViewChild('colList', { static: true }) colList: ElementRef; constructor() { this.data = this._getData(); } ngAfterViewInit() { this.cboFlexGridSortOrder.nativeElement.value = wjGrid.SortOrder[this.flex.sortOrder]; for (let c = 0; c< this.flex.columns.length; c++) { let col = this.flex.columns[c]; if(col.allowSorting) { this.cboColumns.nativeElement.options.add(new Option(col.header, c.toString())); } let sortOrder = this.flex.columns[c].sortOrder == null ? col.allowSorting ? 'Default' : 'null' : wjGrid.SortOrder[this.flex.columns[c].sortOrder]; let li = document.createElement('li'); let liContent = document.createElement('p'); liContent.innerHTML = col.header + " - <b>" + sortOrder + "</b>"; li.appendChild(liContent); this.colList.nativeElement.appendChild(li); } } private _getData() { let countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), data = []; for (let i = 0; i < countries.length; i++) { data.push({ id: i, country: countries[i], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; } cboFlexGridSortOrder_change(s: HTMLElement) { // @ts-ignore this.flex.sortOrder = wjGrid.SortOrder[this.cboFlexGridSortOrder.nativeElement.value]; } cboColumns_change(s: HTMLElement) { if(this.cboColumns.nativeElement.value == "-1") this.cboColumnSortOrder.nativeElement.setAttribute('disabled', 'disabled'); else { this.cboColumnSortOrder.nativeElement.removeAttribute('disabled'); let selCol = parseInt(this.cboColumns.nativeElement.value); this.cboColumnSortOrder.nativeElement.value = this.flex.columns[selCol].sortOrder == null ? null : wjGrid.SortOrder[this.flex.columns[selCol].sortOrder]; } } cboColumnSortOrder_change(s: HTMLElement) { let selCol = parseInt(this.cboColumns.nativeElement.value); let selSortOrder = this.cboColumnSortOrder.nativeElement.value; if(selSortOrder == 'null') selSortOrder = 'Default'; if(selCol != -1) { // @ts-ignore this.flex.columns[selCol].sortOrder = selSortOrder == 'null' ? null : wjGrid.SortOrder[selSortOrder]; this.colList.nativeElement.children[(selCol as any)].innerHTML = this.flex.columns[selCol].header + " - <b>" + selSortOrder + "</b>"; } } } // // enableProdMode(); // Resolve resources (templateUrl, styleUrls etc), After resolution all URLs have been converted into `template` strings. ɵresolveComponentResources(fetch).then(() => { // Bootstrap application bootstrapApplication(AppComponent).catch(err => console.error(err)); });
import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import './styles.css'; // import '@angular/compiler'; import { Component, ElementRef, enableProdMode, ViewChild, ɵresolveComponentResources } from '@angular/core'; import { BrowserModule, bootstrapApplication } from '@angular/platform-browser'; import * as wjGrid from '@mescius/wijmo.grid'; import { WjGridModule } from '@mescius/wijmo.angular2.grid'; // @Component({ standalone: true, imports: [WjGridModule, BrowserModule], selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { data: any[]; // references FlexGrid named 'flex' in the view @ViewChild('flex', { static: true }) flex: wjGrid.FlexGrid; @ViewChild('cboFlexGridSortOrder', { static: true }) cboFlexGridSortOrder: ElementRef; @ViewChild('cboColumns', { static: true }) cboColumns: ElementRef; @ViewChild('cboColumnSortOrder', { static: true }) cboColumnSortOrder: ElementRef; @ViewChild('colList', { static: true }) colList: ElementRef; constructor() { this.data = this._getData(); } ngAfterViewInit() { this.cboFlexGridSortOrder.nativeElement.value = wjGrid.SortOrder[this.flex.sortOrder]; for (let c = 0; c< this.flex.columns.length; c++) { let col = this.flex.columns[c]; if(col.allowSorting) { this.cboColumns.nativeElement.options.add(new Option(col.header, c.toString())); } let sortOrder = this.flex.columns[c].sortOrder == null ? col.allowSorting ? 'Default' : 'null' : wjGrid.SortOrder[this.flex.columns[c].sortOrder]; let li = document.createElement('li'); let liContent = document.createElement('p'); liContent.innerHTML = col.header + " - <b>" + sortOrder + "</b>"; li.appendChild(liContent); this.colList.nativeElement.appendChild(li); } } private _getData() { let countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), data = []; for (let i = 0; i < countries.length; i++) { data.push({ id: i, country: countries[i], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; } cboFlexGridSortOrder_change(s: HTMLElement) { // @ts-ignore this.flex.sortOrder = wjGrid.SortOrder[this.cboFlexGridSortOrder.nativeElement.value]; } cboColumns_change(s: HTMLElement) { if(this.cboColumns.nativeElement.value == "-1") this.cboColumnSortOrder.nativeElement.setAttribute('disabled', 'disabled'); else { this.cboColumnSortOrder.nativeElement.removeAttribute('disabled'); let selCol = parseInt(this.cboColumns.nativeElement.value); this.cboColumnSortOrder.nativeElement.value = this.flex.columns[selCol].sortOrder == null ? null : wjGrid.SortOrder[this.flex.columns[selCol].sortOrder]; } } cboColumnSortOrder_change(s: HTMLElement) { let selCol = parseInt(this.cboColumns.nativeElement.value); let selSortOrder = this.cboColumnSortOrder.nativeElement.value; if(selSortOrder == 'null') selSortOrder = 'Default'; if(selCol != -1) { // @ts-ignore this.flex.columns[selCol].sortOrder = selSortOrder == 'null' ? null : wjGrid.SortOrder[selSortOrder]; this.colList.nativeElement.children[(selCol as any)].innerHTML = this.flex.columns[selCol].header + " - <b>" + selSortOrder + "</b>"; } } } // // enableProdMode(); // Resolve resources (templateUrl, styleUrls etc), After resolution all URLs have been converted into `template` strings. ɵresolveComponentResources(fetch).then(() => { // Bootstrap application bootstrapApplication(AppComponent).catch(err => console.error(err)); });
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo FlexGrid 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/fesm2015/zone.min.js"></script> <!-- SystemJS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.5/system.src.js" integrity="sha512-skZbMyvYdNoZfLmiGn5ii6KmklM82rYX2uWctBhzaXPxJgiv4XBwJnFGr5k8s+6tE1pcR1nuTKghozJHyzMcoA==" crossorigin="anonymous"></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="panel-group"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> Set Sort Order </h4> </div> <div class="panel-body"> <ul class="list-inline"> <li>FlexGrid </li> <li> <select #cboFlexGridSortOrder (change)="cboFlexGridSortOrder_change()"> <option value="AscDesc" selected>AscDesc</option> <option value="DescAsc">DescAsc</option> <option value="AscDescNone">AscDescNone</option> <option value="DescAscNone">DescAscNone</option> </select> </li> </ul> <ul class="list-inline"> <li>Columns </li> <li> <select #cboColumns (change)="cboColumns_change()"> <option value="-1" selected>--Select Column--</option> </select> </li> <li> <select #cboColumnSortOrder (change)="cboColumnSortOrder_change()" disabled> <option value="null" selected>Default</option> <option value="AscDesc">AscDesc</option> <option value="DescAsc">DescAsc</option> <option value="AscDescNone">AscDescNone</option> <option value="DescAscNone">DescAscNone</option> </select> </li> </ul> <ul class="list-inline" #colList> </ul> </div> </div> </div> <wj-flex-grid #flex [deferResizing]="true" [(itemsSource)]="data" [sortOrder]="'AscDesc'"> <wj-flex-grid-column [binding]="'id'" [header]="'ID'" [width]="60" [allowSorting]="false"></wj-flex-grid-column> <wj-flex-grid-column [binding]="'country'" [header]="'Country'" [sortOrder]="'AscDescNone'" ></wj-flex-grid-column> <wj-flex-grid-column [binding]="'sales'" [header]="'Sales'" [sortOrder]="'DescAsc'"></wj-flex-grid-column> <wj-flex-grid-column [binding]="'expenses'" [header]="'Expenses'"></wj-flex-grid-column> </wj-flex-grid> </div>
.wj-flexgrid { height: 150px; margin:10px 0; }
(function (global) { SystemJS.config({ transpiler: './plugin-typescript.js', typescriptOptions: { "target": "ES2022", "module": "system", "emitDecoratorMetadata": true, "experimentalDecorators": true, }, baseURL: 'node_modules/', meta: { 'typescript': { "exports": "ts" }, '*.css': { loader: 'systemjs-plugin-css' }, '*.mjs': { format: 'esm' }, }, paths: { // paths serve as alias 'npm:': '' }, packageConfigPaths: [ '/node_modules/*/package.json', "/node_modules/@angular/*/package.json", "/node_modules/@mescius/*/package.json" ], map: { 'core-js': 'https://cdn.jsdelivr.net/npm/core-js@2.6.12/client/shim.min.js', 'typescript': 'https://cdnjs.cloudflare.com/ajax/libs/typescript/5.2.2/typescript.min.js', "rxjs": "https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.1/rxjs.umd.min.js", 'systemjs-plugin-css': 'https://cdn.jsdelivr.net/npm/systemjs-plugin-css@0.1.37/css.js', '@mescius/wijmo': 'npm:@mescius/wijmo/index.js', '@mescius/wijmo.input': 'npm:@mescius/wijmo.input/index.js', '@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles', '@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures', '@mescius/wijmo.chart': 'npm:@mescius/wijmo.chart/index.js', '@mescius/wijmo.chart.analytics': 'npm:@mescius/wijmo.chart.analytics/index.js', '@mescius/wijmo.chart.animation': 'npm:@mescius/wijmo.chart.animation/index.js', '@mescius/wijmo.chart.annotation': 'npm:@mescius/wijmo.chart.annotation/index.js', '@mescius/wijmo.chart.finance': 'npm:@mescius/wijmo.chart.finance/index.js', '@mescius/wijmo.chart.finance.analytics': 'npm:@mescius/wijmo.chart.finance.analytics/index.js', '@mescius/wijmo.chart.hierarchical': 'npm:@mescius/wijmo.chart.hierarchical/index.js', '@mescius/wijmo.chart.interaction': 'npm:@mescius/wijmo.chart.interaction/index.js', '@mescius/wijmo.chart.radar': 'npm:@mescius/wijmo.chart.radar/index.js', '@mescius/wijmo.chart.render': 'npm:@mescius/wijmo.chart.render/index.js', '@mescius/wijmo.chart.webgl': 'npm:@mescius/wijmo.chart.webgl/index.js', '@mescius/wijmo.chart.map': 'npm:@mescius/wijmo.chart.map/index.js', '@mescius/wijmo.gauge': 'npm:@mescius/wijmo.gauge/index.js', '@mescius/wijmo.grid': 'npm:@mescius/wijmo.grid/index.js', '@mescius/wijmo.grid.detail': 'npm:@mescius/wijmo.grid.detail/index.js', '@mescius/wijmo.grid.filter': 'npm:@mescius/wijmo.grid.filter/index.js', '@mescius/wijmo.grid.search': 'npm:@mescius/wijmo.grid.search/index.js', '@mescius/wijmo.grid.style': 'npm:@mescius/wijmo.grid.style/index.js', '@mescius/wijmo.grid.grouppanel': 'npm:@mescius/wijmo.grid.grouppanel/index.js', '@mescius/wijmo.grid.multirow': 'npm:@mescius/wijmo.grid.multirow/index.js', '@mescius/wijmo.grid.transposed': 'npm:@mescius/wijmo.grid.transposed/index.js', '@mescius/wijmo.grid.transposedmultirow': 'npm:@mescius/wijmo.grid.transposedmultirow/index.js', '@mescius/wijmo.grid.pdf': 'npm:@mescius/wijmo.grid.pdf/index.js', '@mescius/wijmo.grid.sheet': 'npm:@mescius/wijmo.grid.sheet/index.js', '@mescius/wijmo.grid.xlsx': 'npm:@mescius/wijmo.grid.xlsx/index.js', '@mescius/wijmo.grid.selector': 'npm:@mescius/wijmo.grid.selector/index.js', '@mescius/wijmo.grid.cellmaker': 'npm:@mescius/wijmo.grid.cellmaker/index.js', '@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js', '@mescius/wijmo.odata': 'npm:@mescius/wijmo.odata/index.js', '@mescius/wijmo.olap': 'npm:@mescius/wijmo.olap/index.js', '@mescius/wijmo.rest': 'npm:@mescius/wijmo.rest/index.js', '@mescius/wijmo.pdf': 'npm:@mescius/wijmo.pdf/index.js', '@mescius/wijmo.pdf.security': 'npm:@mescius/wijmo.pdf.security/index.js', '@mescius/wijmo.viewer': 'npm:@mescius/wijmo.viewer/index.js', '@mescius/wijmo.xlsx': 'npm:@mescius/wijmo.xlsx/index.js', '@mescius/wijmo.undo': 'npm:@mescius/wijmo.undo/index.js', '@mescius/wijmo.interop.grid': 'npm:@mescius/wijmo.interop.grid/index.js', '@mescius/wijmo.touch': 'npm:@mescius/wijmo.touch/index.js', '@mescius/wijmo.cloud': 'npm:@mescius/wijmo.cloud/index.js', '@mescius/wijmo.barcode': 'npm:@mescius/wijmo.barcode/index.js', '@mescius/wijmo.barcode.common': 'npm:@mescius/wijmo.barcode.common/index.js', '@mescius/wijmo.barcode.composite': 'npm:@mescius/wijmo.barcode.composite/index.js', '@mescius/wijmo.barcode.specialized': 'npm:@mescius/wijmo.barcode.specialized/index.js', "@mescius/wijmo.angular2.chart.analytics": "npm:@mescius/wijmo.angular2.chart.analytics/index.js", "@mescius/wijmo.angular2.chart.animation": "npm:@mescius/wijmo.angular2.chart.animation/index.js", "@mescius/wijmo.angular2.chart.annotation": "npm:@mescius/wijmo.angular2.chart.annotation/index.js", "@mescius/wijmo.angular2.chart.finance.analytics": "npm:@mescius/wijmo.angular2.chart.finance.analytics/index.js", "@mescius/wijmo.angular2.chart.finance": "npm:@mescius/wijmo.angular2.chart.finance/index.js", "@mescius/wijmo.angular2.chart.hierarchical": "npm:@mescius/wijmo.angular2.chart.hierarchical/index.js", "@mescius/wijmo.angular2.chart.interaction": "npm:@mescius/wijmo.angular2.chart.interaction/index.js", "@mescius/wijmo.angular2.chart.radar": "npm:@mescius/wijmo.angular2.chart.radar/index.js", '@mescius/wijmo.angular2.chart.map': 'npm:@mescius/wijmo.angular2.chart.map/index.js', "@mescius/wijmo.angular2.chart": "npm:@mescius/wijmo.angular2.chart/index.js", "@mescius/wijmo.angular2.core": "npm:@mescius/wijmo.angular2.core/index.js", "@mescius/wijmo.angular2.gauge": "npm:@mescius/wijmo.angular2.gauge/index.js", "@mescius/wijmo.angular2.grid.detail": "npm:@mescius/wijmo.angular2.grid.detail/index.js", "@mescius/wijmo.angular2.grid.filter": "npm:@mescius/wijmo.angular2.grid.filter/index.js", "@mescius/wijmo.angular2.grid.grouppanel": "npm:@mescius/wijmo.angular2.grid.grouppanel/index.js", "@mescius/wijmo.angular2.grid.search": "npm:@mescius/wijmo.angular2.grid.search/index.js", "@mescius/wijmo.angular2.grid.multirow": "npm:@mescius/wijmo.angular2.grid.multirow/index.js", "@mescius/wijmo.angular2.grid.sheet": "npm:@mescius/wijmo.angular2.grid.sheet/index.js", '@mescius/wijmo.angular2.grid.transposed': 'npm:@mescius/wijmo.angular2.grid.transposed/index.js', '@mescius/wijmo.angular2.grid.transposedmultirow': 'npm:@mescius/wijmo.angular2.grid.transposedmultirow/index.js', "@mescius/wijmo.angular2.grid": "npm:@mescius/wijmo.angular2.grid/index.js", "@mescius/wijmo.angular2.input": "npm:@mescius/wijmo.angular2.input/index.js", "@mescius/wijmo.angular2.olap": "npm:@mescius/wijmo.angular2.olap/index.js", "@mescius/wijmo.angular2.viewer": "npm:@mescius/wijmo.angular2.viewer/index.js", "@mescius/wijmo.angular2.nav": "npm:@mescius/wijmo.angular2.nav/index.js", "@mescius/wijmo.angular2.directivebase": "npm:@mescius/wijmo.angular2.directivebase/index.js", '@mescius/wijmo.angular2.barcode.common': 'npm:@mescius/wijmo.angular2.barcode.common/index.js', '@mescius/wijmo.angular2.barcode.composite': 'npm:@mescius/wijmo.angular2.barcode.composite/index.js', '@mescius/wijmo.angular2.barcode.specialized': 'npm:@mescius/wijmo.angular2.barcode.specialized/index.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'jszip': 'https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js', '@angular/core': 'npm:@angular/core/fesm2022/core.mjs', '@angular/core/primitives/signals': 'npm:@angular/core/fesm2022/primitives/signals.mjs', '@angular/core/primitives/event-dispatch': 'npm:@angular/core/fesm2022/primitives/event-dispatch.mjs', '@angular/common': 'npm:@angular/common/fesm2022/common.mjs', '@angular/common/http': 'npm:@angular/common/fesm2022/http.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/http': 'npm:@angular/http/fesm2022/http.mjs', '@angular/router': 'npm:@angular/router/fesm2022/router.mjs', '@angular/forms': 'npm:@angular/forms/fesm2022/forms.mjs', }, // packages tells the System loader how to load when no filename and/or no extension packages: { "./src": { defaultExtension: 'ts' }, "node_modules": { defaultExtension: 'js' }, wijmo: { defaultExtension: 'js', } } }); })(this);