Sort in EJ2 TypeScript Spreadsheet control
4 Jul 202419 minutes to read
Sorting helps arranging the data to a specific order in a selected range of cells. You can use the allowSorting
property to enable or disable sorting functionality.
- The default value for
allowSorting
property istrue
.
By default, the sort
module is injected internally into Spreadsheet to perform sorting.
Sort by cell value
In the active Spreadsheet, select a range of cells to sort by cell value. The range sort can be done by any of the following ways:
- Select the sort item in the Ribbon toolbar and choose the ascending or descending item.
-
Right-click the sheet, select the sort item in the context menu and choose the ascending/descending item.
- Use the
sort()
method programmatically.
The cell values can be sorted in the following orders:
- Ascending
- Descending
- Ascending is the default order for sorting.
The sort()
method with empty arguments will sort the selected range by active cell’s column as sort column in ascending order.
- The
beforeSort
event will be triggered before sorting the specified range.- The
sortComplete
event will be triggered after the sort action is completed successfully.
The following code example shows Sort
functionality in the Spreadsheet control.
import { Spreadsheet } from '@syncfusion/ej2-spreadsheet';
import { defaultData } from './datasource.ts';
let spreadsheet: Spreadsheet = new Spreadsheet({
sheets: [{ ranges: [{ dataSource: defaultData }] }],
allowSorting: true,
beforeSort: function (args) {
//code here to handle sorting arguments.
},
sortComplete: function (args) {
spreadsheet.selectRange(args.range);
// code here.
},
dataBound: function () {
if (spreadsheet.activeSheetIndex === 0) {
spreadsheet.sort({ containsHeader: true }, 'A1:H11');
}
}
});
//Render the initialized Spreadsheet
spreadsheet.appendTo('#spreadsheet');
<!DOCTYPE html>
<html lang="en">
<head>
<title>EJ2 SpreadSheet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Typescript UI Controls" />
<meta name="author" content="Syncfusion" />
<link rel="shortcut icon" href="resources/favicon.ico" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-lists/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-grids/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-spreadsheet/styles/material.css" rel="stylesheet" />
<link href="styles.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/shim.min.js"></script>
<script src="system.config.js"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<!--Element which is going to render-->
<div id='loader'>Loading....</div>
<div id='container'>
<div id="spreadsheet"></div>
</div>
</body>
</html>
Data contains header
You can specify whether the selected range of cells contains header. To specify, you need to set the containsHeader
property to true
and pass it as sortOption
arguments of the sort() method.
- If the
containsHeader
property is not set and active cell column’s first cell value type is differed from the second cell value type, the first row data in the range are marked as column headers.
You can also enable or disable this property using beforeSort
event arguments,
let spreadsheet: Spreadsheet = new Spreadsheet({
beforeSort: function (args) {
args.sortOptions.containsHeader = true;
}
});
In the custom sort dialog, the Data contains header
checkbox is checked on load. Thus, the default value for containsHeader
is true
in custom sort dialog.
Case sensitive sort
The default sort functionality of Spreadsheet is a case insensitive sorting. When you want to perform sorting with case sensitive, you need to set the caseSensitive
property to true
and pass it as sortOption
arguments of the sort() method.
Case sensitive sorting is applicable only for cells with alphabets. In ascending order sorting with case sensitive enabled, the cells with lower case text will be placed above the cells with upper case text.
- The default value for the
caseSensitive
property isfalse
.
You can also enable or disable this property using beforeSort
event arguments,
let spreadsheet: Spreadsheet = new Spreadsheet({
beforeSort: function (args) {
args.sortOptions.caseSensitive = true;
}
});
In the custom sort dialog, the Case sensitive
checkbox is unchecked on load as the default value is false
.
Sort multiple columns
When you want to perform sorting on multiple columns, it can be done by any of the following ways:
- Select the
Custom sort…
menu item from the Ribbon toolbar item or context menu item. - Use the
sort()
method programmatically by providing sort criteria.
- The current sorting functionality supports sorting based on cell values only.
Custom sort dialog
The custom sort dialog helps sorting multiple columns in the selected range by utilizing the rich UI. This dialog will be appeared while choosing the Custom sort…
from the Ribbon item or context menu item. By default, sort criteria with the first column name from the selected range will be appeared in the dialog on initial load and it cannot be removed.
You can add multiple criteria using the Add Column
button at the bottom of the dialog. Thus, multiple columns can be specified with different sort order. The newly added sort criteria items can be removed using the delete
icons at the end of each items.
You can refer to the Data contains header
topic to learn more about Data contains header
checkbox. To learn more about Case sensitive
checkbox, you can refer to Case sensitive sort
topic.
Passing sort criteria manually
The multi-column sorting can also be performed manually by passing sort options to the sort()
method programmatically. The sortOption
have the following arguments:
-
sortDescriptors
– Sort criteria collection that holds the collection of field name, sort order, andsortComparer
. -
containsHeader
– Boolean argument that specifies whether the range has headers in it. -
caseSensitive
– Boolean argument that specifies whether the range needs to consider case.
- All the arguments are optional.
- When a
sortDescriptor
is specified without field, the field of the firstsortDescriptor
from the collection will be assigned from active cell’s column name and others will be ignored. Hence, it will act as single column sorting.
import { Spreadsheet, SortDescriptor } from '@syncfusion/ej2-spreadsheet';
import { DataManager } from '@syncfusion/ej2-data';
import { tradeData } from './datasource.ts';
let spreadsheet: Spreadsheet = new Spreadsheet({
sheets: [{ ranges: [{ dataSource: tradeData }] }],
allowSorting: true,
sortComplete: function (args) {
spreadsheet.selectRange(args.range);
// code here.
},
dataBound: function () {
let sortDescriptors: SortDescriptor[] = [
{
field: 'F',
order: 'Ascending'
},
{
field: 'E',
order: 'Ascending'
},
{
field: 'C',
order: 'Descending'
}];
if (spreadsheet.activeSheetIndex === 0) {
spreadsheet.sort({ sortDescriptors: sortDescriptors, containsHeader: true }, 'A1:H30');
}
}
});
//Render the initialized Spreadsheet
spreadsheet.appendTo('#spreadsheet');
<!DOCTYPE html>
<html lang="en">
<head>
<title>EJ2 SpreadSheet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Typescript UI Controls" />
<meta name="author" content="Syncfusion" />
<link rel="shortcut icon" href="resources/favicon.ico" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-lists/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-grids/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-spreadsheet/styles/material.css" rel="stylesheet" />
<link href="styles.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/shim.min.js"></script>
<script src="system.config.js"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<!--Element which is going to render-->
<div id='loader'>Loading....</div>
<div id='container'>
<div id="spreadsheet"></div>
</div>
</body>
</html>
Custom sort comparer
The sortDescriptor
holds the sortComparer
property, which is a function and it is used to customize the sort comparer for specific sort criteria. Each sortDescriptor
can be customized using the custom sort comparer function.
By customizing sort comparer, you can define the sort action as desired.
- The
sortComparer
is an optional property ofsortDescriptor
.
For custom sort comparer example, refer to the [Sort a range by custom list
] below.
Sort a range by custom list
You can also define the sorting of cell values based on your own customized personal list. In this article, custom list is achieved using custom sort comparer
.
In the following demo, the Trustworthiness
column is sorted based on the custom lists Perfect
, Sufficient
, and Insufficient
.
import { Spreadsheet, CellModel } from '@syncfusion/ej2-spreadsheet';
import { DataManager, DataUtil } from '@syncfusion/ej2-data';
import { tradeData } from './datasource.ts';
let spreadsheet: Spreadsheet = new Spreadsheet({
sheets: [{ ranges: [{ dataSource: new DataManager(tradeData) }] }],
dataBound: function () {
if (spreadsheet.activeSheetIndex === 0) {
spreadsheet.sort({sortDescriptors: { field: 'F', sortComparer: mySortComparer }, containsHeader: true}, 'A1:H20');
}
},
sortComplete: function (args) {
spreadsheet.selectRange(args.range);
// code here.
}
});
// custom sort comparer to sort based on the custom list.
let customList: string[] = ['Perfect', 'Sufficient', 'Insufficient'];
function mySortComparer(x: CellModel, y: CellModel): number {
let comparer: Function = DataUtil.fnSort('Ascending');
return comparer(x ? customList.indexOf(x.value) : x, y ? customList.indexOf(y.value) : y);
};
//Render the initialized Spreadsheet
spreadsheet.appendTo('#spreadsheet');
<!DOCTYPE html>
<html lang="en">
<head>
<title>EJ2 SpreadSheet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Typescript UI Controls" />
<meta name="author" content="Syncfusion" />
<link rel="shortcut icon" href="resources/favicon.ico" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-lists/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-grids/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-spreadsheet/styles/material.css" rel="stylesheet" />
<link href="styles.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/shim.min.js"></script>
<script src="system.config.js"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<!--Element which is going to render-->
<div id='loader'>Loading....</div>
<div id='container'>
<div id="spreadsheet"></div>
</div>
</body>
</html>
Known error validations
The following errors have been handled for sorting,
-
Out of range validation: When the selected range is not a used range of the active sheet, it is considered as invalid and the out of range alert with the message
Select a cell or range inside the used range and try again
will be displayed. No sort will be performed if the range is invalid. -
Empty field validation: When the sort criteria does not have a column selected (empty) in the custom sort dialog, it will become invalid, and an error message
Sort criteria column should not be empty
will be displayed onOK
button click. -
Duplicate field validation: When the column names of added sort criteria are repeated more than once in the custom sort dialog, it will become invalid and an error message
<Column name> is mentioned more than once. Duplicate columns must be removed
will be displayed onOK
button click.
Limitations
- Sorting is not supported with formula contained cells.