I am using Ant Design V2.X and I cannot update to a newer version. I inherited code and I am struggling to sort the data according to certain column. It should be ordered once, and not sorted dynamically.
This is what I have within the return() function of my React component:
<Table size="small"
dataSource={this.props.Data}
rowKey={(record) => (record.LedgerId * 100 + record.PositionId).toString()}
pagination={false}
showHeader={true}
>
I was assuming the rowKey would order my data according to the arrow-function, but this is not the case. Can you all guide me how to solve this?
Background info
Within the component, I have the following declaration:
export interface ViewTableProps {
selectedEntity: number,
Data Interfaces.ViewEntry[],
}
and elsewhere
export interface ViewEntry {
//Id: number,
LedgerId: number,
PositionId: number,
Value: number,
children: ViewEntry[]
}
Related and not-so related posts
Antd table - sort dosen't work with render
Can't sort Column in Ant Design Table in Gatsby site
Sort an antd (Ant Design) table that has selection enabled
If you want to add actual sorters to your individual columns, you'd need to write sort functions in the sorter property of your column definitions. If you want to sort the entire dataset by default, you could sort the dataSource before passing it to the table.
Column sort from their docs:
{
title: 'Age',
dataIndex: 'age',
defaultSortOrder: 'descend',
sorter: (a, b) => a.age - b.age,
},
If you want a "default sort," you can just make a function to sort data outside the table;
const sortData = (data) => {
// Call slice to create a new Array and prevent mutating it if it's stored in state
return data.slice().sort((a, b) => a.myKey - b.myKey);
}
...
<Table size="small"
dataSource={sortData(this.props.Data)}
rowKey={(record) => (record.LedgerId * 100 + record.PositionId).toString()}
pagination={false}
showHeader={true}
>
If you would like to order dates, I recommend this:
import moment from 'moment';
and add
{
title: 'Date',
dataIndex: 'date',
key: "date",
sorter: (a, b) => moment(a.date).unix() - moment(b.date).unix()
},
Related
Currently I'm trying to build an input based table
const columns = [{
title: 'Items',
dataIndex: `Items`,
key:`Items`
}];
Then I loop thru an array for the rest of the columns that are for checkbox
countryList.forEach((id) => {
const data = CountryDetail[id].name;
columns.push({
title: data,
dataIndex: data,
key: data,
render: (value, rowId) => (
<Checkbox
checked={value}
...
)
})
});
The datasource will be dynamically generated as well. Since I need to get the boolean values from the checkboxes, is there a way to give all checkbox unique id for identification for submission? I had tried creating with function but since it is in class component, usestate could not be used.
const data = [{
Items: 'Chips',
Japan: true,
...
}]
I'm fetching object (contract) from DB, it contains few fields, one of them is an array of objects (products). I have antd table with column Products and I would like to fill it with product names.
For example, my contract object also has account object, and the way I use dataIndex there is like this:
{
title: 'Account',
dataIndex: ['account', 'name'],
key: 'account',
align: 'center',
sorter: (a, b) => a.length - b.length
}
That works fine! But Account is not an array.
Here is code with issue:
{
title: 'Products',
dataIndex: ['products'],
key: 'products',
align: 'center',
filters: []
}
Here is how I map data that is send to component above which has to fill table:
return data.map((contract) => ({
key: contract._id,
account: contract.account,
products: [contract.products],
}));
I tried returning just contract.products, tried returning Object.values(contract.products), tried to JSON.stringify(contract.products) but then I don't know how to parse it in column and take just name...
The only way I managed to set name was by not sending object. Example:
return data.map((contract) => ({
key: contract._id,
account: contract.account,
products: contract.products.map(product => product.name),
}));
This would indeed solve this problem, but it would made me make another asyncThunk method where I would return whole array of objects.
Hope that I described that well,this is for my college project and it's bean bugging me whole day.
I would be very grateful if someone knows how can I solve this.
According to Antd documentation for column dataIndex, it will only accept a string or an array of strings for nested paths.
dataIndex - Display field of the data record, support nest path by string array - string | string[ ]
So I don't think you can pass an array of objects to dataIndex.
The only way around that I can think of would be to convert the array to a string before passing it to your table.
To do that you can use .join() method to add space and a comma between your array items.
const convertArrayToString = (array) => array.join(', ');
And before returning you could use the above function: Example:
return data.map((contract) => ({
key: contract._id,
account: contract.account,
products: convertArrayToString(contract.products),
}));
We love the DataGrid for its build in sorting and filtering capabilities.
However grid based layouts are troublesome on small screen devices. So we started looking at Card based layouts. There we miss the sorting and filtering we appreciate in the DataGrid.
Now we are wondering if there is an example to use cards as UI layer for the DataGrid, where a column in the grid would become a row in the card. Cards should flow to available columns.
How can we do this?
This is a partial answer, however, there is a renderCell prop in the column configuration that accepts a function that can include a component.
So, to replace a row with a card, I might include a column that renders your components with all of the values you would otherwise express one by one in a series of columns. For instance:
const columns = [
{ field: 'id', headerName: 'ID', hide: true }, // keep this
{ field: 'myCombinedView', hide: false, flex: 1, renderCell: (props) => <Component {...props} /> },
I can imagine including a single, hidden column that represents a concatenation of the values you want to sort on. From here, specify the sort function for the Component column that uses the hidden value.
The following code sample is pulled from the DataGrid storyboard:
() => {
const columns = getColumns();
// compute a new field for purposes of sorting
columns[columns.length] = {
field: 'username',
valueGetter: (params) =>
`${params.getValue('name') || 'unknown'}_${params.getValue('age') || 'x'}`,
sortComparator: (v1, v2, cellParams1, cellParams2) => cellParams1.row.age - cellParams2.row.age,
width: 150,
};
return (
<div className="grid-container">
<XGrid
rows={getRows()}
columns={columns}
// use the field as the sort model
sortModel={[{ field: columns[columns.length - 1].field, sort: 'asc' }]}
/>
</div>
);
}
How to dynamically select/change the sort criteria is not something I can see a clear path for.
I go problem with sorting data in table because when I using sorter with render function sort work only time
{
title: 'App',
dataIndex: 'location',
render: location => location.join(', '),
sorter: true
}, {
title: 'Priority',
dataIndex: 'priority',
sorter: true
}
Sorter buttons in column dosen't change and i got the same data from table handle event function. I dont want write sorter function on frontend because i do this on backend
you can update antd-3.11.0 version
If you want to send api calls upon sorting, you will be using onChange function for this. Details can be found in the api of antd table.
I am using ant-design react components to make a dashboard and have used a table component where I can define how the filters and sorters once the data is populated.
If have a requirement where I want to apply default sorting(descending) on ID column and in environment column I want prod to be selected by default(to show only prod alerts by default). Since I can't ask usage question on ant-design website, I wanted to know if someone knows about it and can help me with this. I am open to a different approach if you can share.
function onChange(pagination, filters, sorter) {
console.log('params', pagination, filters, sorter);
let order_by = sorter.field;
if (sorter.order == 'descend'){
order_by = `-${order_by}`;
console.log(order_by);
}
let offset = ((pagination.current - 1) * pagination.pageSize);
let url = `${baseUrl}&offset=${offset}&ordering=${order_by}`;
this.fetchResults(url);
}
output for console.log
>>> params Object { showQuickJumper: true, pageSize: 20, current: 1, total: 301 } Object { env: Array['prod'], incident_type: Array['loadChk'] } Object { }
Use defaultSortOrder like defaultSortOrder: 'descend'
You can pass a default the sortOrder value: This can be ascend, descend or false; that would allow you to set a default sort order.
https://ant.design/components/table/#Column
As far as the default filter goes, you need to set the filteredValue prop as #Panther has mentioned above.
You can use defaultFilteredValue for setting a default filter value. Give the value you want to display as a string array.
Eg:
{
title: 'STATUS',
dataIndex: 'status',
key: 'status',
filters: createFilterArray(status),
defaultFilteredValue : ['Open'],
onFilter: (value, filters) => filters.status.indexOf(value) === 0,
},
For default sort use defaultSortOrder. It can take ascend and descend as values.