Data Sorting

JSS provides a great deal of flexibility and control when it comes to sorting, enabling the developer to:

  • Create a sorting handler method to customize the JavaScript sorting behavior.
  • Use the onbeforesorting event to intercept, change, or cancel the sorting results for the user.

You can sort the data grid using the context menu, double-clicking the column header, or invoking the orderBy method.

Documentation

Methods

The developer can call the spreadsheet sorting programmatically using the following methods.

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

The onbeforesort can be used to intercept, change or cancel the order results.

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

Initial Settings

The following property helps to define the sorting behavior.

Property Description
sorting: function Define a custom sorting handler.
sorting(direction: Boolean) : function
columnSorting: bool Allow the user to sort the spreadsheet by columns. Default: true

Native sorting handler

The following code is the default sorting method. You can customize the function to create different sorting results.

 ABCDEF
1
2
3
4
5
6
  • See this example in JavaScript
  • See this example in React
  • See this example in VueJS
  • See this example in Angular
<html>
<script src="https://jspreadsheet.com/v10/jspreadsheet.js"></script>
<script src="https://jsuites.net/v5/jsuites.js"></script>
<link rel="stylesheet" href="https://jspreadsheet.com/v10/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>
/**
 * Default sorting method
 * @param {boolean} Direction
 * @param {number} Column number starting on zero.
 */
const sortingHandler = function(direction, column) {
    // Handler
    return function(a, b) {
        let valueA = a[1];
        let valueB = b[1];

        if (! direction) {
            return (valueA === '' && valueB !== '') ? 1 : (valueA !== '' && valueB === '') ? -1 :
                (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0;
        } else {
            return (valueA === '' && valueB !== '') ? 1 : (valueA !== '' && valueB === '') ? -1 :
                (valueA > valueB) ? -1 : (valueA < valueB) ? 1 : 0;
        }
    }
}

// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

// Create the spreadsheet
let table = jspreadsheet(document.getElementById('spreadsheet'), {
    worksheets: [{
        minDimensions: [6,6],
    }],
    sorting: sortingHandler,
});
</script>
</html>
import React, { useRef } from "react";
import { Spreadsheet, Worksheet } from "@jspreadsheet/react";

const license = 'ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

/**
 * Default sorting method
 * @param {boolean} Direction
 * @param {number} Column number starting on zero.
 */
const sortingHandler = function(direction, column) {
    // Handler
    return function(a, b) {
        let valueA = a[1];
        let valueB = b[1];

        if (! direction) {
            return (valueA === '' && valueB !== '') ? 1 : (valueA !== '' && valueB === '') ? -1 :
                (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0;
        } else {
            return (valueA === '' && valueB !== '') ? 1 : (valueA !== '' && valueB === '') ? -1 :
                (valueA > valueB) ? -1 : (valueA < valueB) ? 1 : 0;
        }
    }
}

export default function App() {
    // Spreadsheet array of worksheets
    const spreadsheet = useRef();

    // Render component
    return (
        <Spreadsheet ref={spreadsheet} license={license} sorting={sortingHandler}>
            <Worksheet />
        </Spreadsheet>
    );
}
<template>
    <Spreadsheet ref="spreadsheet" :license="license" :sorting="sortingHandler">
        <Worksheet :minDimensions="[10,10]" />
    </Spreadsheet>
</template>

<script>
import { Spreadsheet, Worksheet } from "@jspreadsheet/vue";

const license = 'ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

/**
 * Default sorting method
 * @param {boolean} Direction
 * @param {number} Column number starting on zero.
 */
const sortingHandler = function(direction, column) {
    // Handler
    return function(a, b) {
        let valueA = a[1];
        let valueB = b[1];

        if (! direction) {
            return (valueA === '' && valueB !== '') ? 1 : (valueA !== '' && valueB === '') ? -1 :
                (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0;
        } else {
            return (valueA === '' && valueB !== '') ? 1 : (valueA !== '' && valueB === '') ? -1 :
                (valueA > valueB) ? -1 : (valueA < valueB) ? 1 : 0;
        }
    }
}

// Create the data grid component
export default {
    components: {
        Spreadsheet,
        Worksheet,
    },
    data() {
        return {
            sortingHandler,
            license,
        };
    }
}
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet";

import "jspreadsheet/dist/jspreadsheet.css"
import "jsuites/dist/jsuites.css"

// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

/**
 * Default sorting method
 * @param {boolean} Direction
 * @param {number} Column number starting on zero.
 */
const sortingHandler = function(direction, column) {
    // Handler
    return function(a, b) {
        let valueA = a[1];
        let valueB = b[1];

        if (! direction) {
            return (valueA === '' && valueB !== '') ? 1 : (valueA !== '' && valueB === '') ? -1 :
                (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0;
        } else {
            return (valueA === '' && valueB !== '') ? 1 : (valueA !== '' && valueB === '') ? -1 :
                (valueA > valueB) ? -1 : (valueA < valueB) ? 1 : 0;
        }
    }
}

@Component({
    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: [{
                minDimensions: [10,10],
            }],
            sorting: sortingHandler,
        });
    }
}

Examples

Basic sorting

The following example shows the behavior when sorting through different column types.

Double click in any data grid column header below

Change the spreadsheet column order programmatically

 ABCDEFG
1Mazda200120002006-01-014532906
2Peugeot201050002005-01-01235115
3Honda Fit200930002004-01-012143642
4Honda CRV201060002003-01-0156.112112.22

  • See this example in JavaScript
  • See this example in React
  • See this example in VueJS
  • See this example in Angular
<html>
<script src="https://jspreadsheet.com/v10/jspreadsheet.js"></script>
<script src="https://jsuites.net/v5/jsuites.js"></script>
<link rel="stylesheet" href="https://jspreadsheet.com/v10/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" />

<div id="spreadsheet"></div>

<script>
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

// 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'],
        ],
        columns: [
            { type: 'text', width:300 },
            { type: 'text', width:80 },
            { type: 'text', width:100 },
            { type: 'calendar', width:100 },
            { type: 'number', width:100 },
            { type: 'number', width:100 },
            { type: 'number', width:100 },
        ],
    }]
});
document.getElementById("orderby").onclick = () => table[0].orderBy(document.getElementById('columnNumber').value);
</script>

<br/>
<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' id="orderby"/>

</html>
import React, { useRef } from "react";
import { Spreadsheet, Worksheet } from "@jspreadsheet/react";

const license = 'ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

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'],
    ];
    // Columns
    const columns = [
        { type: 'text', width:300 },
        { type: 'text', width:80 },
        { type: 'text', width:100 },
        { type: 'calendar', width:100 },
        { type: 'number', width:100 },
        { type: 'number', width:100 },
        { type: 'number', width:100 },
    ];

    // Render component
    return (
        <>
            <Spreadsheet ref={spreadsheet} license={license}>
                <Worksheet data={data} columns={columns} />
            </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" :license="license">
        <Worksheet :data="data" :columns="columns" />
    </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 { Spreadsheet, Worksheet } from "@jspreadsheet/vue";

const license = 'ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

// Create the data grid component
export default {
    components: {
        Spreadsheet,
        Worksheet,
    },
    methods: {
        sortColumn() {
            this.$refs.spreadsheet.current[0].orderBy(this.$refs.select.value.value);
        }
    },
    data() {
        // 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'],
        ];
        // Columns
        const columns = [
            { type: 'text', width:300 },
            { type: 'text', width:80 },
            { type: 'text', width:100 },
            { type: 'calendar', width:100 },
            { type: 'number', width:100 },
            { type: 'number', width:100 },
            { type: 'number', width:100 },
        ];

        return {
            data,
            columns,
            license,
        };
    }
}
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet";

import "jspreadsheet/dist/jspreadsheet.css"
import "jsuites/dist/jsuites.css"

// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

@Component({
    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'],
                ],
                columns: [
                    { type: 'text', width:300 },
                    { type: 'text', width:80 },
                    { type: 'text', width:100 },
                    { type: 'calendar', width:100 },
                    { type: 'number', width:100 },
                    { type: 'number', width:100 },
                    { type: 'number', width:100 },
                ],
            }]
        });
    }
}

Custom sorting handler

The following example shows how to customize the spreadsheet sorting behavior using the sorting property.

 AB
1Spreadsheets1
2Grids2
3Tables3
4Plugins4
5
6
7
8
  • See this example in JavaScript
  • See this example in React
  • See this example in VueJS
  • See this example in Angular
<html>
<script src="https://jspreadsheet.com/v10/jspreadsheet.js"></script>
<script src="https://jsuites.net/v5/jsuites.js"></script>
<link rel="stylesheet" href="https://jspreadsheet.com/v10/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" />

<div id="spreadsheet"></div>

<script>
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

// 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/react";

const license = 'ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

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} license={license} sorting={sorting}>
            <Worksheet data={data} columns={columns} />
        </Spreadsheet>
    );
}
<template>
    <Spreadsheet ref="spreadsheet" :license="license" :sorting="sorting">
        <Worksheet :data="data" :columns="columns" />
    </Spreadsheet>
</template>

<script>
import { Spreadsheet, Worksheet } from "@jspreadsheet/vue";

const license = 'ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

// 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,
            license,
        };
    }
}
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet";

import "jspreadsheet/dist/jspreadsheet.css"
import "jsuites/dist/jsuites.css"

// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('ZTNhZDMwMjQyZGFmNmVhOGEzN2IwYWJlZDRmMjQ1MmQ4NTg3NTFjODdlYzk4N2QyMGNjZDk1ZTIxNDA0YjNlNjRmMzIxNTlmMDRjNDI2YWM5MzIxODdhZTIxZjcyYTI2MmExZDI2YWVlZjE2OTVmMGU4NjI2YmU3N2JhNjE4ZjgsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpRME1ERXlOelUwTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

@Component({
    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;
                    }
                }
            }
        });
    }
}