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.

app.jsx
index.html
app.css
data.jsx
Copy to CodeMine
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 (<div 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}>
                  <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}>
                  <option value="-1" selected>--Select Column--</option>
                </select>
              </li>
              <li>
                <select ref={cboColumnSortOrderRef} onChange={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 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>
    </div>);
}
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 (<div 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}> <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}> <option value="-1" selected>--Select Column--</option> </select> </li> <li> <select ref={cboColumnSortOrderRef} onChange={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 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> </div>); } 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);