Sorting (React)

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 React.

The demo is being dynamically compiled to support real-time code editing... For quicker access to features, switch to the "JavaScript" tab for a smoother experience! :)
app.jsx
index.html
app.css
data.jsx
Copy to CodeMine
loading...
import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import ReactDOM from 'react-dom/client'; import React, { useEffect, useRef } from 'react'; import useEvent from 'react-use-event-hook'; import * as wjcGrid from '@mescius/wijmo.react.grid'; import * as wjGrid from '@mescius/wijmo.grid'; import './app.css'; import { data } from './data'; function App() { const flexRef = useRef(null); const cboFlexGridSortOrderRef = useRef(null); const cboColumnsRef = useRef(null); const cboColumnSortOrderRef = useRef(null); const colListRef = useRef(null); const flexInitialized = useEvent((flexgrid) => { flexRef.current = flexgrid; }); useEffect(() => { cboFlexGridSortOrderRef.current.value = wjGrid.SortOrder[flexRef.current.sortOrder]; for (let c = 0; c < flexRef.current.columns.length; c++) { let col = flexRef.current.columns[c]; if (col.allowSorting) { cboColumnsRef.current.options.add(new Option(col.header, c.toString())); } let sortOrder = flexRef.current.columns[c].sortOrder == null ? col.allowSorting ? 'Default' : 'null' : wjGrid.SortOrder[flexRef.current.columns[c].sortOrder]; let li = document.createElement('li'); let liContent = document.createElement('p'); liContent.innerHTML = col.header + " - <b>" + sortOrder + "</b>"; li.appendChild(liContent); colListRef.current.appendChild(li); } }, []); const cboFlexGridSortOrder_change = () => { flexRef.current.sortOrder = wjGrid.SortOrder[cboFlexGridSortOrderRef.current.value]; }; const cboColumns_change = () => { if (cboColumnsRef.current.value == "-1") cboColumnSortOrderRef.current.setAttribute('disabled', 'disabled'); else { cboColumnSortOrderRef.current.removeAttribute('disabled'); let selCol = parseInt(cboColumnsRef.current.value); cboColumnSortOrderRef.current.value = flexRef.current.columns[selCol].sortOrder == null ? null : wjGrid.SortOrder[flexRef.current.columns[selCol].sortOrder]; } }; const cboColumnSortOrder_change = () => { let selCol = parseInt(cboColumnsRef.current.value); let selSortOrder = cboColumnSortOrderRef.current.value; if (selSortOrder == 'null') selSortOrder = 'Default'; if (selCol != -1) { flexRef.current.columns[selCol].sortOrder = selSortOrder == 'null' ? null : wjGrid.SortOrder[selSortOrder]; colListRef.current.children[selCol].innerHTML = flexRef.current.columns[selCol].header + " - <b>" + selSortOrder + "</b>"; } }; return (<main className="container-fluid"> <div className="panel-group"> <div className="panel panel-default"> <div className="panel-heading"> <h4 className="panel-title"> Set Sort Order </h4> </div> <div className="panel-body"> <ul className="list-inline"> <li>FlexGrid </li> <li> <select ref={cboFlexGridSortOrderRef} onChange={cboFlexGridSortOrder_change} aria-label='FlexGrid SortOrder'> <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 className="list-inline"> <li>Columns </li> <li> <select ref={cboColumnsRef} onChange={cboColumns_change} aria-label='Select Column'> <option value="-1" selected>--Select Column--</option> </select> </li> <li> <select ref={cboColumnSortOrderRef} onChange={cboColumnSortOrder_change} aria-label='Column SortOrder' 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 className="list-inline" ref={colListRef}> </ul> </div> </div> </div> <wjcGrid.FlexGrid deferResizing={true} itemsSource={data} initialized={flexInitialized} sortOrder="AscDesc"> <wjcGrid.FlexGridColumn binding="id" header="ID" width={60} allowSorting={false}/> <wjcGrid.FlexGridColumn binding="country" header="Country" sortOrder="AscDescNone"/> <wjcGrid.FlexGridColumn binding="sales" header="Sales" sortOrder="DescAsc"/> <wjcGrid.FlexGridColumn binding="expenses" header="Expenses"/> </wjcGrid.FlexGrid> </main>); } const container = document.getElementById('app'); if (container) { const root = ReactDOM.createRoot(container); root.render(<App />); }
import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import ReactDOM from 'react-dom/client'; import React, { useEffect, useRef } from 'react'; import useEvent from 'react-use-event-hook'; import * as wjcGrid from '@mescius/wijmo.react.grid'; import * as wjGrid from '@mescius/wijmo.grid'; import './app.css'; import { data } from './data'; function App() { const flexRef = useRef(null); const cboFlexGridSortOrderRef = useRef(null); const cboColumnsRef = useRef(null); const cboColumnSortOrderRef = useRef(null); const colListRef = useRef(null); const flexInitialized = useEvent((flexgrid) => { flexRef.current = flexgrid; }); useEffect(() => { cboFlexGridSortOrderRef.current.value = wjGrid.SortOrder[flexRef.current.sortOrder]; for (let c = 0; c < flexRef.current.columns.length; c++) { let col = flexRef.current.columns[c]; if (col.allowSorting) { cboColumnsRef.current.options.add(new Option(col.header, c.toString())); } let sortOrder = flexRef.current.columns[c].sortOrder == null ? col.allowSorting ? 'Default' : 'null' : wjGrid.SortOrder[flexRef.current.columns[c].sortOrder]; let li = document.createElement('li'); let liContent = document.createElement('p'); liContent.innerHTML = col.header + " - <b>" + sortOrder + "</b>"; li.appendChild(liContent); colListRef.current.appendChild(li); } }, []); const cboFlexGridSortOrder_change = () => { flexRef.current.sortOrder = wjGrid.SortOrder[cboFlexGridSortOrderRef.current.value]; }; const cboColumns_change = () => { if (cboColumnsRef.current.value == "-1") cboColumnSortOrderRef.current.setAttribute('disabled', 'disabled'); else { cboColumnSortOrderRef.current.removeAttribute('disabled'); let selCol = parseInt(cboColumnsRef.current.value); cboColumnSortOrderRef.current.value = flexRef.current.columns[selCol].sortOrder == null ? null : wjGrid.SortOrder[flexRef.current.columns[selCol].sortOrder]; } }; const cboColumnSortOrder_change = () => { let selCol = parseInt(cboColumnsRef.current.value); let selSortOrder = cboColumnSortOrderRef.current.value; if (selSortOrder == 'null') selSortOrder = 'Default'; if (selCol != -1) { flexRef.current.columns[selCol].sortOrder = selSortOrder == 'null' ? null : wjGrid.SortOrder[selSortOrder]; colListRef.current.children[selCol].innerHTML = flexRef.current.columns[selCol].header + " - <b>" + selSortOrder + "</b>"; } }; return (<main className="container-fluid"> <div className="panel-group"> <div className="panel panel-default"> <div className="panel-heading"> <h4 className="panel-title"> Set Sort Order </h4> </div> <div className="panel-body"> <ul className="list-inline"> <li>FlexGrid </li> <li> <select ref={cboFlexGridSortOrderRef} onChange={cboFlexGridSortOrder_change} aria-label='FlexGrid SortOrder'> <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 className="list-inline"> <li>Columns </li> <li> <select ref={cboColumnsRef} onChange={cboColumns_change} aria-label='Select Column'> <option value="-1" selected>--Select Column--</option> </select> </li> <li> <select ref={cboColumnSortOrderRef} onChange={cboColumnSortOrder_change} aria-label='Column SortOrder' 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 className="list-inline" ref={colListRef}> </ul> </div> </div> </div> <wjcGrid.FlexGrid deferResizing={true} itemsSource={data} initialized={flexInitialized} sortOrder="AscDesc"> <wjcGrid.FlexGridColumn binding="id" header="ID" width={60} allowSorting={false}/> <wjcGrid.FlexGridColumn binding="country" header="Country" sortOrder="AscDescNone"/> <wjcGrid.FlexGridColumn binding="sales" header="Sales" sortOrder="DescAsc"/> <wjcGrid.FlexGridColumn binding="expenses" header="Expenses"/> </wjcGrid.FlexGrid> </main>); } const container = document.getElementById('app'); if (container) { const root = ReactDOM.createRoot(container); root.render(<App />); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo Wijmo FlexGrid Sorting</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.40/system.src.js" integrity="sha512-G6mEj6h18+m3MvzdviSDfPle/TfH0//cXcB33AKlNR/Rha0yQsKefDZKRTkIZos97HEGq2JMV1RT5ybMoQ3WsQ==" crossorigin="anonymous"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div id="app"></div> </body> </html>
.wj-flexgrid { height: 150px; margin: 10px 0; }
function getData() { let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'], 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; } export const data = getData();
(function (global) { window.process = { env: { NODE_ENV: "production" } } System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'jszip': 'npm:jszip/dist/jszip.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.grid.immutable': 'npm:@mescius/wijmo.grid.immutable/index.js', '@mescius/wijmo.touch': 'npm:@mescius/wijmo.touch/index.js', '@mescius/wijmo.cloud': 'npm:@mescius/wijmo.cloud/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.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.react.chart.analytics": "npm:@mescius/wijmo.react.chart.analytics/index.js", "@mescius/wijmo.react.chart.animation": "npm:@mescius/wijmo.react.chart.animation/index.js", "@mescius/wijmo.react.chart.annotation": "npm:@mescius/wijmo.react.chart.annotation/index.js", "@mescius/wijmo.react.chart.finance.analytics": "npm:@mescius/wijmo.react.chart.finance.analytics/index.js", "@mescius/wijmo.react.chart.finance": "npm:@mescius/wijmo.react.chart.finance/index.js", "@mescius/wijmo.react.chart.hierarchical": "npm:@mescius/wijmo.react.chart.hierarchical/index.js", "@mescius/wijmo.react.chart.interaction": "npm:@mescius/wijmo.react.chart.interaction/index.js", "@mescius/wijmo.react.chart.radar": "npm:@mescius/wijmo.react.chart.radar/index.js", "@mescius/wijmo.react.chart": "npm:@mescius/wijmo.react.chart/index.js", "@mescius/wijmo.react.core": "npm:@mescius/wijmo.react.core/index.js", '@mescius/wijmo.react.chart.map': 'npm:@mescius/wijmo.react.chart.map/index.js', "@mescius/wijmo.react.gauge": "npm:@mescius/wijmo.react.gauge/index.js", "@mescius/wijmo.react.grid.detail": "npm:@mescius/wijmo.react.grid.detail/index.js", "@mescius/wijmo.react.grid.filter": "npm:@mescius/wijmo.react.grid.filter/index.js", "@mescius/wijmo.react.grid.grouppanel": "npm:@mescius/wijmo.react.grid.grouppanel/index.js", '@mescius/wijmo.react.grid.search': 'npm:@mescius/wijmo.react.grid.search/index.js', "@mescius/wijmo.react.grid.multirow": "npm:@mescius/wijmo.react.grid.multirow/index.js", "@mescius/wijmo.react.grid.sheet": "npm:@mescius/wijmo.react.grid.sheet/index.js", '@mescius/wijmo.react.grid.transposed': 'npm:@mescius/wijmo.react.grid.transposed/index.js', '@mescius/wijmo.react.grid.transposedmultirow': 'npm:@mescius/wijmo.react.grid.transposedmultirow/index.js', '@mescius/wijmo.react.grid.immutable': 'npm:@mescius/wijmo.react.grid.immutable/index.js', "@mescius/wijmo.react.grid": "npm:@mescius/wijmo.react.grid/index.js", "@mescius/wijmo.react.input": "npm:@mescius/wijmo.react.input/index.js", "@mescius/wijmo.react.olap": "npm:@mescius/wijmo.react.olap/index.js", "@mescius/wijmo.react.viewer": "npm:@mescius/wijmo.react.viewer/index.js", "@mescius/wijmo.react.nav": "npm:@mescius/wijmo.react.nav/index.js", "@mescius/wijmo.react.base": "npm:@mescius/wijmo.react.base/index.js", '@mescius/wijmo.react.barcode.common': 'npm:@mescius/wijmo.react.barcode.common/index.js', '@mescius/wijmo.react.barcode.composite': 'npm:@mescius/wijmo.react.barcode.composite/index.js', '@mescius/wijmo.react.barcode.specialized': 'npm:@mescius/wijmo.react.barcode.specialized/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'react': 'npm:react/index.js', 'react-dom': 'npm:react-dom/index.js', 'react-dom/client': 'npm:react-dom/client.js', "scheduler": "npm:scheduler/index.js", 'redux': 'npm:redux/dist/redux.min.js', 'react-redux': 'npm:react-redux/dist/react-redux.min.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', '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', "react-use-event-hook": "npm:react-use-event-hook/dist/esm/useEvent.js", }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'jsx' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);