Single Sorting
By default, the Infinite Table is sortable - clicking a column will sort the grid by that column. Clicking again will reverse the sort and a third click on the column removes the sort altogether.
At any point, clicking another column header removes any existing column sort and performs a new sort by the clicked column.
This is called single sorting - only one column can be sorted at a time.
Technically, it's the
<DataSource />
that's being sorted, not the <InfiniteTable />
component.By default, clicking a column header sorts the column.
View Mode
Fork Forkimport { InfiniteTable, DataSource } from '@infinite-table/infinite-react'; import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; country: string; city: string; currency: string; email: string; preferredLanguage: string; hobby: string; salary: number; age: number; }; const columns: InfiniteTablePropColumns<Developer> = { firstName: { field: 'firstName', header: 'First Name' }, age: { field: 'age', header: 'Age' }, salary: { field: 'salary', header: 'Salary', type: 'number', }, country: { field: 'country', header: 'Country' }, preferredLanguage: { field: 'preferredLanguage' }, id: { field: 'id' }, hobby: { field: 'hobby' }, city: { field: 'city' }, currency: { field: 'currency' }, }; export default function LocalUncontrolledSingleSortingExample() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource}> <InfiniteTable<Developer> columns={columns} columnDefaultWidth={120} /> </DataSource> </> ); } const dataSource: Developer[] = [ { id: 0, firstName: 'Nya', country: 'India', city: 'Unnao', age: 24, currency: 'JPY', preferredLanguage: 'TypeScript', salary: 60000, hobby: 'sports', email: 'Nya44@gmail.com', }, { id: 1, firstName: 'Axel', country: 'Mexico', city: 'Cuitlahuac', age: 46, currency: 'USD', preferredLanguage: 'TypeScript', salary: 100000, hobby: 'sports', email: 'Axel93@hotmail.com', }, { id: 2, firstName: 'Gonzalo', country: 'United Arab Emirates', city: 'Fujairah', age: 54, currency: 'JPY', preferredLanguage: 'Go', salary: 120000, hobby: 'photography', email: 'Gonzalo_McGlynn34@gmail.com', }, { id: 3, firstName: 'Sherwood', country: 'Mexico', city: 'Tlacolula de Matamoros', age: 43, currency: 'CHF', preferredLanguage: 'Rust', salary: 99000, hobby: 'cooking', email: 'Sherwood_McLaughlin65@hotmail.com', }, { id: 4, firstName: 'Alexandre', country: 'France', city: 'Persan', age: 23, currency: 'EUR', preferredLanguage: 'Go', salary: 97000, hobby: 'reading', email: 'Alexandre_Harber@hotmail.com', }, { id: 5, firstName: 'Mariane', country: 'United States', city: 'Hays', age: 34, currency: 'EUR', preferredLanguage: 'TypeScript', salary: 58000, hobby: 'cooking', email: 'Mariane0@hotmail.com', }, { id: 6, firstName: 'Rosalind', country: 'Mexico', city: 'Nuevo Casas Grandes', age: 33, currency: 'AUD', preferredLanguage: 'JavaScript', salary: 198000, hobby: 'dancing', email: 'Rosalind69@gmail.com', }, { id: 7, firstName: 'Lolita', country: 'Sweden', city: 'Delsbo', age: 22, currency: 'JPY', preferredLanguage: 'TypeScript', salary: 200000, hobby: 'cooking', email: 'Lolita.Hayes@hotmail.com', }, { id: 8, firstName: 'Tre', country: 'Germany', city: 'Bad Camberg', age: 11, currency: 'GBP', preferredLanguage: 'TypeScript', salary: 200000, hobby: 'sports', email: 'Tre28@gmail.com', }, { id
Apply a default sort order#
You can specify a default sort order by using the
defaultSortInfo
prop - specify an object like// sort by `firstName`, in ascending order defaultSortInfo = { field: 'firstName', dir: 1 };
COPY
defaultSortInfo
is an uncontrolled property, so updating the sorting by clicking a column header does not require you to respond to user actions via the onSortInfoChange
.Uncontrolled sorting is managed internally by the
<DataSource />
component, so you don't need to worry about it.For controlled sorting, make sure you use the
sortInfo
prop and the onSortInfoChange
callback.The
age
column is sorted in ascending order.View Mode
Fork Forkimport { InfiniteTable, DataSource, DataSourceSingleSortInfo, } from '@infinite-table/infinite-react'; import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; email: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const columns: InfiniteTablePropColumns<Developer> = { firstName: { field: 'firstName' }, age: { field: 'age' }, country: { field: 'country' }, preferredLanguage: { field: 'preferredLanguage' }, salary: { field: 'salary', type: 'number', }, canDesign: { field: 'canDesign' }, stack: { field: 'stack' }, id: { field: 'id' }, hobby: { field: 'hobby' }, city: { field: 'city' }, currency: { field: 'currency' }, }; const defaultSortInfo: DataSourceSingleSortInfo<Developer> = { field: 'age', dir: 1, }; export default function LocalUncontrolledSingleSortingExample() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource} defaultSortInfo={defaultSortInfo} > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={120} /> </DataSource> </> ); } const dataSource: Developer[] = [ { id: 0, firstName: 'Nya', lastName: 'Klein', country: 'India', city: 'Unnao', age: 24, currency: 'JPY', preferredLanguage: 'TypeScript', stack: 'backend', canDesign: 'yes', salary: 60000, hobby: 'sports', email: 'Nya44@gmail.com', }, { id: 1, firstName: 'Axel', lastName: 'Runolfsson', country: 'Mexico', city: 'Cuitlahuac', age: 46, currency: 'USD', preferredLanguage: 'TypeScript', stack: 'backend', canDesign: 'no', salary: 100000, hobby: 'sports', email: 'Axel93@hotmail.com', }, { id: 2, firstName: 'Gonzalo', lastName: 'McGlynn', country: 'United Arab Emirates', city: 'Fujairah', age: 54, currency: 'JPY', preferredLanguage: 'Go', stack: 'frontend', canDesign: 'yes', salary: 120000, hobby: 'photography', email: 'Gonzalo_McGlynn34@gmail.com', }, { id: 3, firstName: 'Sherwood', lastName: 'McLaughlin', country: 'Mexico', city: 'Tlacolula de Matamoros', age: 43, currency: 'CHF', preferredLanguage: 'Rust', stack: 'backend', canDesign: 'no', salary: 99000, hobby: 'cooking', email: 'Sherwood_McLaughlin65@hotmail.com', }, { id: 4, firstName: 'Alexandre', lastName: 'Harber', country: 'France', city: 'Persan', age: 23, currency: 'EUR', preferredLanguage: 'Go', stack: 'backend', canDesign: 'yes', salary: 97000, hobby: 'reading', email: 'Alexandre_Harber@hotmail.com', }, { id: 5, firstName: 'Mariane', lastName: 'Schroeder', country: 'United States', city: 'Hays', age: 34, currency: 'EUR', preferredLanguage: 'TypeScript', stack: 'backend', canDesign: 'no', salary: 58000, hobby: 'cooking', email: 'Mariane0@hotmail.com', }, { id: 6, firstName: 'Rosalind', lastName: 'Mills', country: 'Mexico', city: 'Nuevo Casas Grandes', age: 33, currency: 'AUD', preferredLanguage: 'JavaScript', stack: 'frontend', canDesign: 'no', salary: 198000, hobby: 'dancing', email: 'Rosalind69@gmail.com', }, { id: 7, firstName: 'Lolita', lastName: 'Hayes', country: 'Sweden', city: 'Delsbo', age: 22, currency: 'JPY', preferredLanguage: 'TypeScript', stack: 'full-stack', canDesign: 'yes', salary: 200000, hobby: 'cooking', email: 'Lolita.Hayes@hotmail.com', }, { id: 8, firstName: 'Tre', lastName: 'Boyle', country: 'Germany', city: 'Bad Camberg', age: 11, currency: 'GBP', preferredLanguage: 'TypeScript', stack: 'backend', canDesign: 'yes', salary: 200000, hobby: 'sports', email: 'Tre28@gmail.com', }, { id
Controlled sorting#
For controlled, single sorting, use the
sortInfo
as an object like this:// sort by `firstName`, in ascending order sortInfo = { field: 'firstName', dir: 1 };
COPY
or you can specify
null
for explicit no sorting// no sorting sortInfo = null;
COPY
When you use controlled sorting via
sortInfo
, make sure you also listen to onSortInfoChange
for changes, to get notifications when sorting is changed by the user. Also, for controlled sorting, it's your responsibility to sort the data - read bellow in the controlled and uncontrolled section.Describing the sort order#
To describe the sorting order, you have to use an object that has the following shape:
dir
-1 | -1
- the direction of the sortingfield?
-keyof DATA_TYPE
- the field to sort by - optional.id?
-string
- if you don't sort by a field, you can specify an id of the column this sorting is bound to. Note that columns have avalueGetter
, which will be used when doing local sorting and the column is not bound to an exact field.type?
- the sort type - one of the keys insortTypes
- eg"string"
,"number"
,"date"
- will be used for local sorting, to provide the proper comparison function.
Multiple Sorting#
If you want to use multiple sorting, specify an array of objects like
// sort by age in descending order, then by `firstName` in ascending order sortInfo = [ { field: 'age', type: 'number', dir: -1 }, { field: 'firstName', dir: 1 }, ]; // no sorting sortInfo = [];
COPY
This allows sorting by multiple fields (to which columns are bound) - you can specify however many you want - so when sorting two objects in the
DataSource
, the first sortInfo
is used to compare the two, and then, on equal values, the next sortInfo
is used and so on.This table allows sorting multiple columns - initially the
country
column is sorted in descending order and the salary
column is sorted in ascending order. Click the salary
column to toggle the column sort to descending. Clicking it a second time will remove it from the sort altogether.View Mode
Fork Forkimport { InfiniteTable, DataSource, DataSourceData, } from '@infinite-table/infinite-react'; import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource: DataSourceData<Developer> = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + `/developers100-sql?`) .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { firstName: { field: 'firstName' }, country: { field: 'country' }, salary: { field: 'salary', type: 'number', }, age: { field: 'age' }, id: { field: 'id' }, canDesign: { field: 'canDesign' }, preferredLanguage: { field: 'preferredLanguage' }, stack: { field: 'stack' }, hobby: { field: 'hobby' }, city: { field: 'city' }, currency: { field: 'currency' }, }; const domProps = { style: { height: '90vh' } }; const shouldReloadData = { sortInfo: false, }; export default function LocalUncontrolledMultiSortingExampleWithRemoteData() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource} defaultSortInfo={[ { field: 'country', dir: -1 }, { field: 'salary', dir: 1 }, ]} shouldReloadData={shouldReloadData} > <InfiniteTable<Developer> domProps={domProps} columns={columns} columnDefaultWidth={120} /> </DataSource> </>
View Mode
Fork Forkimport { InfiniteTable, DataSource, DataSourceData, } from '@infinite-table/infinite-react'; import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource: DataSourceData<Developer> = ({ sortInfo }) => { if (sortInfo && !Array.isArray(sortInfo)) { sortInfo = [sortInfo]; } const args = [ sortInfo ? 'sortInfo=' + JSON.stringify( sortInfo.map((s) => ({ field: s.field, dir: s.dir, })), ) : null, ] .filter(Boolean) .join('&'); return fetch('https://infinite-table.com/.netlify/functions/json-server' + `/developers100-sql?` + args) .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { salary: { field: 'salary', type: 'number', }, age: { field: 'age' }, canDesign: { field: 'canDesign' }, country: { field: 'country' }, preferredLanguage: { field: 'preferredLanguage' }, firstName: { field: 'firstName' }, stack: { field: 'stack' }, id: { field: 'id' }, hobby: { field: 'hobby' }, city: { field: 'city' }, currency: { field: 'currency' }, }; const shouldReloadData = { sortInfo: true, }; export default function RemoteUncontrolledMultiSortingExample() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource} defaultSortInfo={[ { field: 'salary', dir: -1, }, ]} shouldReloadData={shouldReloadData} > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={120} /> </DataSource> </>
If you use uncontrolled sorting via
defaultSortInfo
there's no way to switch between single and multiple sorting after the component is mounted. If you have this use-case, you need to use the controlled sortInfo
prop.Understanding sort mode#
Sorting can be done both locally in the browser and remotely on the server. For configuring where sorting is performed you need to specify the
shouldReloadData.sortInfo
. Possible values for shouldReloadData.sortInfo
are false
(for local sorting) and true
(for remote sorting).This allows you fine-grained control on how sorting is done, either in the client or on the server.
Uncontrolled sorting#
If you use uncontrolled sorting (namely you don't care about updating the
sortInfo
yourself as a result of user interaction - via onSortInfoChange
) - then by default, the shouldReloadData.sortInfo
is false
(so local sorting) unless you specify otherwise.You can initially render the component with no sort state or you can specify a default sorting state, via the uncontrolled prop
defaultSortInfo
.// initially render the component with ascending sorting on `firstName` field // also, note this is an array, so multiple sorting will be enabled const defaultSortInfo = [{ field: 'firstName', dir: 1 }]; <DataSource<Developer> primaryKey="id" data={data} defaultSortInfo={defaultSortInfo} > <InfiniteTable /> </DataSource>;
COPY
If your data is remote and you want the sorting to happen on the backend, you can still use uncontrolled sorting, but you need to specify
shouldReloadData.sortInfo=true
.Using remote sort mode will trigger a call to the
data
function whenever sorting changes, so you can re-fetch the data from the backend, according to the new sortInfo
.Whe
local
uncontrolled sorting is used, the <DataSource />
sorts the data internally, based on the existing sorting information. To start with a specific sortInfo
, use the defaultSortInfo
prop. As the user interacts with the table, onSortInfoChange
is being called with updated sort info and the <DataSource />
continues to sort the data accordingly.The
defaultSortInfo
prop is an uncontrolled prop, so it's all managed inside the <DataSource />
component and you can't change it from the outside. If you need to control it from outside the component, use the controlled sortInfo prop - read the next section for more detailsControlled Sorting#
When you use the controlled
sortInfo
prop, by default the shouldReloadData.sortInfo
is true
(remote sorting), unless you specify otherwise.Also, be aware that when the user interacts with the DataGrid when controlled sorting is configured, the
sortInfo
prop will not update automatically - you need to listen to onSortInfoChange
and update the sortInfo
yourself.Just like with uncontrolled sorting, updating the controlled
sortInfo
when shouldReloadData.sortInfo=true
, will trigger a call to the data
function, so new sorted data can be re-fetched.When the controlled
sortInfo
is combined with shouldReloadData.sortInfo=false
, the <DataSource />
will sort the data internally, on any changes of the sorting information.But remember it's your responsibility to update the
sortInfo
prop when the user interacts with the DataGrid.Both controlled
sortInfo
and uncontrolled defaultSortInfo
work in combination with onSortInfoChange
- use it to be notified when sorting changes, so you can react and update your app accordingly if needed.Local Sorting#
When you use uncontrolled sorting locally, the
<DataSource />
will sort the data internally, based on the defaultSortInfo
prop. Local sorting is available for any configured data
source - be it an array or a function that returns a promise.You can use
onDataParamsChange
, which is called whenever any of the sorting, filtering, grouping or pivoting information changes.View Mode
Fork Forkimport { InfiniteTable, DataSource, DataSourceData, } from '@infinite-table/infinite-react'; import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource: DataSourceData<Developer> = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + `/developers100-sql?`) .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { preferredLanguage: { field: 'preferredLanguage' }, salary: { field: 'salary', type: 'number', }, age: { field: 'age' }, canDesign: { field: 'canDesign' }, country: { field: 'country' }, firstName: { field: 'firstName' }, stack: { field: 'stack' }, id: { field: 'id' }, hobby: { field: 'hobby' }, city: { field: 'city' }, currency: { field: 'currency' }, }; const shouldReloadData = { sortInfo: false, }; export default function LocalUncontrolledSingleSortingExampleWithRemoteData() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource} defaultSortInfo={{ field: 'salary', dir: -1 }} shouldReloadData={shouldReloadData} > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={220} /> </DataSource> </>
View Mode
Fork Forkimport { InfiniteTable, DataSource, DataSourceData, } from '@infinite-table/infinite-react'; import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource: DataSourceData<Developer> = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + `/developers100-sql?`) .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { preferredLanguage: { field: 'preferredLanguage' }, salary: { field: 'salary', type: 'number', }, age: { field: 'age' }, canDesign: { field: 'canDesign' }, country: { field: 'country' }, firstName: { field: 'firstName' }, stack: { field: 'stack' }, id: { field: 'id' }, hobby: { field: 'hobby' }, city: { field: 'city' }, currency: { field: 'currency' }, }; const shouldReloadData = { sortInfo: false, }; export default function LocalUncontrolledSingleSortingExampleWithRemoteData() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource} defaultSortInfo={{ field: 'salary', dir: -1 }} shouldReloadData={shouldReloadData} > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={220} /> </DataSource> </>
Remote Sorting#
Sorting remotely makes a lot of sense when using a function as your
data
source. Whenever the sort information is changed, the function will be called with all the information needed to retrieve the data from the remote endpoint.For remote sorting, make sure you specify
shouldReloadData.sortInfo=true
- if you don't, the data will also be sorted locally in the browser (which most of the times will be harmless, but it means wasted CPU cycles).View Mode
Fork Forkimport { InfiniteTable, DataSource, DataSourceData, DataSourcePropSortInfo, } from '@infinite-table/infinite-react'; import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource: DataSourceData<Developer> = ({ sortInfo }) => { if (sortInfo && !Array.isArray(sortInfo)) { sortInfo = [sortInfo]; } const args = [ sortInfo ? 'sortInfo=' + JSON.stringify( sortInfo.map((s) => ({ field: s.field, dir: s.dir, })), ) : null, ] .filter(Boolean) .join('&'); return fetch('https://infinite-table.com/.netlify/functions/json-server' + `/developers100-sql?` + args) .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { preferredLanguage: { field: 'preferredLanguage' }, salary: { field: 'salary', type: 'number', }, age: { field: 'age' }, canDesign: { field: 'canDesign' }, country: { field: 'country' }, firstName: { field: 'firstName' }, stack: { field: 'stack' }, id: { field: 'id' }, hobby: { field: 'hobby' }, city: { field: 'city' }, currency: { field: 'currency' }, }; export default function RemoteControlledMultiSortingExample() { const [sortInfo, setSortInfo] = React.useState< DataSourcePropSortInfo<Developer> >([ { field: 'salary', dir: -1, }, ]); const shouldReloadData = { sortInfo: true, }; return ( <> <DataSource<Developer> primaryKey="id" data={dataSource} sortInfo={sortInfo} shouldReloadData={shouldReloadData} onSortInfoChange={setSortInfo} > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={220} /> </DataSource> </>
In the example above, remote and controlled sorting are combined - because
shouldReloadData.sortInfo=true
is specified, the <DataSource />
will call the data
function whenever sorting changes, and will pass in the dataParams
object that contains the sort information.Custom Sort Functions with sortTypes
By default, all columns are sorted as strings, even if they contain numeric values. To make numeric columns sort as numbers, you need to specify a
dataType
for the column, or, a column sortType
.There are two
dataType
values that can be used:"string"
"number"
Each dataType has its own sorting function and its own filtering operators & functions.
Sorting works in combination with the
sortTypes
property, which is an object with keys being sort types and values being functions that compare two values of the same type.const sortTypes = { string: (a, b) => a.localeCompare(b), number: (a, b) => a - b, };
COPY
Those are the two sort types supported by default.
The functions specified in the
sortTypes
object need to always sort data in ascending order.A column can choose to use a specific
columns.sortType
, in which case, for local sorting, the corresponding sort function will be used, or, it can simply specify a dataType
and the sortType
with the same name will be used (when no explicit sortType
is defined).To conclude, the
dataType
of a column will be used as the sortType
and filterType
, when those are not explicitly specified.View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTableColumn, } from '@infinite-table/infinite-react'; import * as React from 'react'; export type CarSale = { id: number; make: string; model: string; year: number; sales: number; color: string; }; const carsales: CarSale[] = [ { make: 'Volkswagen', model: 'GTI', year: 2009, sales: 6, color: 'red', id: 0, }, { make: 'Honda', model: 'Element 2WD', year: 2009, sales: 739, color: 'red', id: 1, }, { make: 'Acura', model: 'RDX 4WD', year: 2008, sales: 2, color: 'magenta', id: 2, }, { make: 'Honda', model: 'Fit', year: 2009, sales: 211, color: 'blue', id: 3, }, { make: 'Mazda', model: '6', year: 2009, sales: 31, color: 'blue', id: 4, }, { make: 'Acura', model: 'TSX', year: 2009, sales: 14, color: 'yellow', id: 5, }, { make: 'Acura', model: 'TSX', year: 2010, sales: 14, color: 'red', id: 6, }, { make: 'Audi', model: 'A3', year: 2009, sales: 2, color: 'magenta', id: 7, }, ]; const columns: Record<string, InfiniteTableColumn<CarSale>> = { color: { field: 'color', sortType: 'color' }, make: { field: 'make' }, model: { field: 'model' }, sales: { field: 'sales', sortType: 'number', }, year: { field: 'year', sortType: 'number', }, }; const newSortTypes = { color: (one: string, two: string) => { if (one === 'magenta') { // magenta comes first return -1; } if (two === 'magenta') { // magenta comes first return 1; } return one.localeCompare(two); }, }; export default function DataTestPage() { return ( <> <DataSource<CarSale> data={carsales} primaryKey="id" defaultSortInfo={{ field: 'color', dir: 1, type: 'color', }} sortTypes={newSortTypes} > <InfiniteTable<CarSale> columns={columns} /> </DataSource> </>
In this example, for the
"color"
column, we specified column.sortType="color"
- we could have passed that as column.dataType
instead, but if the grid had filtering, it wouldn't know what filters to use for "color" - so we used column.sortType
to only change how the data is sorted.When you provide a
defaultSortInfo
prop and the sorting information uses a custom sortType
, make sure you specify that as the type
property of the sorting info object.defaultSortInfo={{ field: 'color', dir: 1, // note this custom sort type type: 'color', }}
COPY
You will need to have a property for that type in your
sortTypes
object as well.sortTypes={{ color: (a, b) => //... }}
COPY
Replacing the sort function#
While there are many ways to customise sorting, including the
sortTypes
mentioned above, you might want to completely replace the sorting function used by the <DataSource />
component.You can do this by configuring the
sortFunction
prop.const sortFunction = (sortInfo, dataArray) => { // sort the dataArray according to the sortInfo // and return the sorted array // return sortedDataArray; }; <DataSource<T> sortFunction={sortFunction} />;
COPY
The function specified in the
sortFunction
prop is called with the sortInfo
as the first argument and the data array as the second. It should return a sorted array, as per the sortInfo
it was called with.When
sortFunction
is specified, shouldReloadData.sortInfo
will be forced to false
, as the sorting is done in the browser.View Mode
Fork Forkimport { InfiniteTable, DataSource, DataSourceSingleSortInfo, multisort, } from '@infinite-table/infinite-react'; import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; email: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const columns: InfiniteTablePropColumns<Developer> = { preferredLanguage: { field: 'preferredLanguage' }, salary: { field: 'salary', type: 'number', }, age: { field: 'age' }, canDesign: { field: 'canDesign' }, country: { field: 'country' }, firstName: { field: 'firstName' }, stack: { field: 'stack' }, id: { field: 'id' }, hobby: { field: 'hobby' }, city: { field: 'city' }, currency: { field: 'currency' }, }; const defaultSortInfo: DataSourceSingleSortInfo<Developer> = { field: 'stack', dir: 1, }; const sortFunction = ( sortInfo: DataSourceSingleSortInfo<Developer>[], arr: Developer[], ) => { // you call the default sorting const result = multisort<Developer>(sortInfo, arr); // and also apply your custom sorting // result.sort((a, b) => { // }) return result; }; export default function LocalUncontrolledSingleSortingExample() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource} defaultSortInfo={defaultSortInfo} sortFunction={sortFunction} > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={220} /> </DataSource> </> ); } const dataSource: Developer[] = [ { id: 0, firstName: 'Nya', lastName: 'Klein', country: 'India', city: 'Unnao', age: 24, currency: 'JPY', preferredLanguage: 'TypeScript', stack: 'backend', canDesign: 'yes', salary: 60000, hobby: 'sports', email: 'Nya44@gmail.com', }, { id: 1, firstName: 'Axel', lastName: 'Runolfsson', country: 'Mexico', city: 'Cuitlahuac', age: 46, currency: 'USD', preferredLanguage: 'TypeScript', stack: 'backend', canDesign: 'no', salary: 100000, hobby: 'sports', email: 'Axel93@hotmail.com', }, { id: 2, firstName: 'Gonzalo', lastName: 'McGlynn', country: 'United Arab Emirates', city: 'Fujairah', age: 54, currency: 'JPY', preferredLanguage: 'Go', stack: 'frontend', canDesign: 'yes', salary: 120000, hobby: 'photography', email: 'Gonzalo_McGlynn34@gmail.com', }, { id: 3, firstName: 'Sherwood', lastName: 'McLaughlin', country: 'Mexico', city: 'Tlacolula de Matamoros', age: 43, currency: 'CHF', preferredLanguage: 'Rust', stack: 'backend', canDesign: 'no', salary: 99000, hobby: 'cooking', email: 'Sherwood_McLaughlin65@hotmail.com', }, { id: 4, firstName: 'Alexandre', lastName: 'Harber', country: 'France', city: 'Persan', age: 23, currency: 'EUR', preferredLanguage: 'Go', stack: 'backend', canDesign: 'yes', salary: 97000, hobby: 'reading', email: 'Alexandre_Harber@hotmail.com', }, { id: 5, firstName: 'Mariane', lastName: 'Schroeder', country: 'United States', city: 'Hays', age: 34, currency: 'EUR', preferredLanguage: 'TypeScript', stack: 'backend', canDesign: 'no', salary: 58000, hobby: 'cooking', email: 'Mariane0@hotmail.com', }, { id: 6, firstName: 'Rosalind', lastName: 'Mills', country: 'Mexico', city: 'Nuevo Casas Grandes', age: 33, currency: 'AUD', preferredLanguage: 'JavaScript', stack: 'frontend', canDesign: 'no', salary: 198000, hobby: 'dancing', email: 'Rosalind69@gmail.com', }, { id: 7, firstName: 'Lolita', lastName: 'Hayes', country: 'Sweden', city: 'Delsbo', age: 22, currency: 'JPY', preferredLanguage: 'TypeScript', stack: 'full-stack', canDesign: 'yes', salary: 200000, hobby: 'cooking', email: 'Lolita.Hayes@hotmail.com', }, { id: 8, firstName: 'Tre', lastName: 'Boyle', country: 'Germany', city: 'Bad Camberg', age: 11, currency: 'GBP', preferredLanguage: 'TypeScript', stack: 'backend', canDesign: 'yes', salary: 200000, hobby: 'sports', email: 'Tre28@gmail.com', }, { id