Data Grid Column Sorting

Jspreadsheet CE enables developers to create custom sorting handlers to override the default data grid sorting behaviour. Rows can be sorted through the context menu, double-clicking column headers, or programmatically using the orderBy method.

Documentation

Methods

The following method can be invoked to execute sorting programmatically:

Method Description
orderBy Sort the data grid.
@param {number} columnNumber - Sort by column number
@param {boolean} direction: false (asc), true (desc)
orderBy(columnNumber: Number, direction: Boolean) : void

Events

Event Description
onsort onsort(worksheet: Object, column: Number, direction: Number, newValue: Array) : void

Initial Settings

You can define the sorting behaviour of your spreadsheet using the following properties:

Property Description
sorting: function Defines a custom sorting handler. Use this to implement your specific sorting logic.
sorting(direction: Boolean) : function
columnSorting: boolean Enables or disables column-based sorting for the spreadsheet.Default: true

Examples

Basic Sorting

The example below demonstrates sorting behaviour across various column types.

Double-click on any data grid column header below to observe sorting functionality.

<html> <script src="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.js"></script> <script src="https://jsuites.net/v5/jsuites.js"></script> <link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.css" type="text/css" /> <link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" /> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" /> <div id="spreadsheet"></div> <p><select id='btn2'> <option value='0'>Column 1</option> <option value='1'>Column 2</option> <option value='2'>Column 3</option> <option value='3'>Column 4</option> </select> <input type='button' value='Sort column' id="btn1" /></p> <script> // Create the spreadsheet let table = jspreadsheet(document.getElementById('spreadsheet'), { worksheets: [{ data: [ ['Mazda', 2001, 2000, '2006-01-01', '453.00', '2', '=E1*F1'], ['Peugeot', 2010, 5000, '2005-01-01', '23.00', '5', '=E2*F2'], ['Honda Fit', 2009, 3000, '2004-01-01', '214.00', '3', '=E3*F3'], ['Honda CRV', 2010, 6000, '2003-01-01', '56.11', '2', '=E4*F4'], ] }] }); document.getElementById("btn1").onclick = (e) => table[0].orderBy(e.target.previousElementSibling.value); </script> </html> 
import React, { useRef } from "react"; import { Spreadsheet, Worksheet } from "@jspreadsheet-ce/react"; import "jsuites/dist/jsuites.css"; import "jspreadsheet-ce/dist/jspreadsheet.css"; export default function App() { // Spreadsheet array of worksheets const spreadsheet = useRef(); const select = useRef(); // Data const data = [ ['Mazda', 2001, 2000, '2006-01-01', '453.00', '2', '=E1*F1'], ['Peugeot', 2010, 5000, '2005-01-01', '23.00', '5', '=E2*F2'], ['Honda Fit', 2009, 3000, '2004-01-01', '214.00', '3', '=E3*F3'], ['Honda CRV', 2010, 6000, '2003-01-01', '56.11', '2', '=E4*F4'], ]; // Render component return ( <> <Spreadsheet ref={spreadsheet}> <Worksheet data={data} /> </Spreadsheet> <select ref={select}> <option value='0'>Column 1</option> <option value='1'>Column 2</option> <option value='2'>Column 3</option> <option value='3'>Column 4</option> </select> <input type='button' value='Sort column' onClick={() => spreadsheet.current[0].orderBy(select.current.value)} /> </> ); } 
<template> <Spreadsheet ref="spreadsheet"> <Worksheet :data="data" /> </Spreadsheet> <select ref="select"> <option value="0">Column 1</option> <option value="1">Column 2</option> <option value="2">Column 3</option> <option value="3">Column 4</option> </select> <input type="button" value="Sort column" @click="sortColumn" /> </template> <script> import { ref } from 'vue'; import { Spreadsheet, Worksheet } from "@jspreadsheet-ce/vue"; import "jsuites/dist/jsuites.css"; import "jspreadsheet-ce/dist/jspreadsheet.css"; export default { components: { Spreadsheet, Worksheet, }, setup() { const spreadsheet = ref(null); const select = ref(null); const data = [ ['Mazda', 2001, 2000, '2006-01-01', '453.00', '2', '=E1*F1'], ['Peugeot', 2010, 5000, '2005-01-01', '23.00', '5', '=E2*F2'], ['Honda Fit', 2009, 3000, '2004-01-01', '214.00', '3', '=E3*F3'], ['Honda CRV', 2010, 6000, '2003-01-01', '56.11', '2', '=E4*F4'], ]; const sortColumn = () => { const columnIndex = select.value.value; spreadsheet.value.current[0].orderBy(columnIndex); }; return { spreadsheet, select, data, sortColumn }; } } </script> 
import { Component, ViewChild, ElementRef } from "@angular/core"; import jspreadsheet from "jspreadsheet-ce"; import "jspreadsheet-ce/dist/jspreadsheet.css" import "jsuites/dist/jsuites.css" @Component({ standalone: true, selector: "app-root", template: ` <div #spreadsheet></div> <select id='columnNumber'> <option value='0'>Column 1</option> <option value='1'>Column 2</option> <option value='2'>Column 3</option> <option value='3'>Column 4</option> </select> <input type='button' value='Sort column' (click)="this.worksheets[0].orderBy(this.select.nativeElement.value)">` }) export class AppComponent { @ViewChild("spreadsheet") spreadsheet: ElementRef; @ViewChild("select") select: ElementRef; // Worksheets worksheets: jspreadsheet.worksheetInstance[]; // Create a new data grid ngAfterViewInit() { // Create spreadsheet this.worksheets = jspreadsheet(this.spreadsheet.nativeElement, { worksheets: [{ data: [ ['Mazda', 2001, 2000, '2006-01-01', '453.00', '2', '=E1*F1'], ['Peugeot', 2010, 5000, '2005-01-01', '23.00', '5', '=E2*F2'], ['Honda Fit', 2009, 3000, '2004-01-01', '214.00', '3', '=E3*F3'], ['Honda CRV', 2010, 6000, '2003-01-01', '56.11', '2', '=E4*F4'], ] }] }); } } 

Custom Sorting Handler

The example below demonstrates how to customize spreadsheet sorting behaviour using the sorting property.

<html> <script src="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.js"></script> <script src="https://jsuites.net/v5/jsuites.js"></script> <link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.css" type="text/css" /> <link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" /> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" /> <div id="spreadsheet"></div> <script> // Create the spreadsheet jspreadsheet(document.getElementById('spreadsheet'), { worksheets: [{ data: [ ['Spreadsheets', 1], ['Grids', 2], ['Tables', 3], ['Plugins', 4], ['', ''], ['', ''], ['', ''], ['', ''], ], columns: [ { type: 'text', width:200 }, { type: 'text', width:400 }, ], }], sorting: function(direction, column) { return function(a, b) { let valueA = a[1]; let valueB = b[1]; // Consider blank rows in the sorting if (! direction) { return (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0; } else { return (valueA > valueB) ? -1 : (valueA < valueB) ? 1 : 0; } } } }); </script> </html> 
import React, { useRef } from "react"; import { Spreadsheet, Worksheet } from "@jspreadsheet-ce/react"; import "jsuites/dist/jsuites.css"; import "jspreadsheet-ce/dist/jspreadsheet.css"; export default function App() { // Spreadsheet array of worksheets const spreadsheet = useRef(); // Data const data = [ ['Spreadsheets', 1], ['Grids', 2], ['Tables', 3], ['Plugins', 4], ['', ''], ['', ''], ['', ''], ['', ''], ]; // Columns const columns = [ { type: 'text', width:200 }, { type: 'text', width:400 }, ]; // Sorting handler const sorting = (direction, column) => { return (a, b) => { let valueA = a[1]; let valueB = b[1]; // Consider blank rows in the sorting if (! direction) { return (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0; } else { return (valueA > valueB) ? -1 : (valueA < valueB) ? 1 : 0; } } } // Render component return ( <Spreadsheet ref={spreadsheet} sorting={sorting}> <Worksheet data={data} columns={columns} /> </Spreadsheet> ); } 
<template> <Spreadsheet ref="spreadsheet" :sorting="sorting"> <Worksheet :data="data" :columns="columns" /> </Spreadsheet> </template> <script> import { Spreadsheet, Worksheet } from "@jspreadsheet-ce/vue"; import "jsuites/dist/jsuites.css"; import "jspreadsheet-ce/dist/jspreadsheet.css"; // Create the data grid component export default { components: { Spreadsheet, Worksheet, }, methods: { // Sorting handler sorting(direction, column) { return (a, b) => { let valueA = a[1]; let valueB = b[1]; // Consider blank rows in the sorting if (! direction) { return (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0; } else { return (valueA > valueB) ? -1 : (valueA < valueB) ? 1 : 0; } } } }, data() { // Data const data = [ ['Spreadsheets', 1], ['Grids', 2], ['Tables', 3], ['Plugins', 4], ['', ''], ['', ''], ['', ''], ['', ''], ]; // Columns const columns = [ { type: 'text', width:200 }, { type: 'text', width:400 }, ]; return { data, columns, }; } } </script> 
import { Component, ViewChild, ElementRef } from "@angular/core"; import jspreadsheet from "jspreadsheet-ce"; import "jspreadsheet-ce/dist/jspreadsheet.css" import "jsuites/dist/jsuites.css" @Component({ standalone: true, selector: "app-root", template: `<div #spreadsheet></div>` }) export class AppComponent { @ViewChild("spreadsheet") spreadsheet: ElementRef; // Worksheets worksheets: jspreadsheet.worksheetInstance[]; // Create a new data grid ngAfterViewInit() { // Create spreadsheet this.worksheets = jspreadsheet(this.spreadsheet.nativeElement, { worksheets: [{ data: [ ['Spreadsheets', 1], ['Grids', 2], ['Tables', 3], ['Plugins', 4], ['', ''], ['', ''], ['', ''], ['', ''], ], columns: [ { type: 'text', width:200 }, { type: 'text', width:400 }, ], }], sorting: function(direction, column) { return function(a, b) { let valueA = a[1]; let valueB = b[1]; // Consider blank rows in the sorting if (! direction) { return (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0; } else { return (valueA > valueB) ? -1 : (valueA < valueB) ? 1 : 0; } } } }); } }