I created a custom data table component using primereact. I have two components which are holding Uparrow and DownArrow for sorting. They are not working as expected. Here is the code.
sortData = () => {
const { sortField, sortOrder } = this.props;
if (sortField) {
// Create a sorted copy of the data based on the sortField and sortOrder.
const sorted = [...this.props.data].sort((a, b) => {
const aValue = a[sortField];
const bValue = b[sortField];
// Determine if the field values are numerical.
const isNumerical = !isNaN(parseFloat(aValue)) && !isNaN(parseFloat(bValue));
let result = 0;
if (isNumerical) {
// If the values are numerical, compare them directly.
result = sortOrder === 1 ? aValue - bValue : bValue - aValue;
} else {
// If the values are not numerical, perform a string-based comparison.
result = sortOrder === 1 ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
}
return result;
});
// Update the dataToDisplay state with the sorted data.
this.setState({ dataToDisplay: sorted });
}}
This is my sorting Logic and I am passing it in
handleSortClick = (field: string) => {
const { sortField, sortOrder } = this.state;
// Toggle the sortOrder if the same column is clicked again
const newSortOrder = field === sortField ? -sortOrder : 1;
// Update the state with the new sorting field and order
this.setState({
sortField: field,
sortOrder: newSortOrder,
});
// Trigger the onSortChange callback to sort the data externally
this.props.onSortChange(field, newSortOrder);}
and using in the components as click events.
<DataTable
value={dataToDisplayPaginated}
stripedRows
scrollable
className="custom-data-table-scroll"
>
{/* Check if the checkbox option is enabled and add checkbox column if true. */}
{checkbox && (
<Column
key="checkbox"
header={
<Checkbox
className="custom-checkbox"
checked={selectAll}
onChange={this.toggleAllRows}
/>
}
body={(rowData) => (
<Checkbox
className="custom-checkbox"
checked={selectedRows.some((row) => row.id === rowData.id)}
onChange={() => this.toggleRow(rowData)}
/>
)}
/>
)}
{React.Children.map(this.props.children, (child: ReactNode) => {
if (React.isValidElement<ColumnProps>(child)) {
const columnProps = child.props;
const isSortable = columnProps.sortField === sortField;
const upArrowClickHandler = () => {
if (isSortable && columnProps.sortField) {
this.handleSortClick(columnProps.sortField);
}
};
const downArrowClickHandler = () => {
if (isSortable && columnProps.sortField) {
this.handleSortClick(columnProps.sortField);
}
};
return React.cloneElement(child as React.ReactElement<ColumnProps>, {
header: (
<div className="column-header">
<span className="column-title">{this.getHeader(columnProps.header as string)}</span>
{isSortable && (
<div className="sorting-icons">
<button onClick={upArrowClickHandler}><UpArrow /></button>
<button onClick={downArrowClickHandler}><DownArrow /></button>
</div>
)}
</div>
),
});
}
return null;
})}
</DataTable>
Like this. I am able to click those buttons, but the sorting is not happening. Once it's done I want to pass the sortable property from data table to the component that I am using it as a boolean. I am using primereact column component for column. If I make the sortable to true I am getting the icons for sorting beside the column header from primereact. Instead of that I need to get these icons and able to sort.
please help me with this. Thanks in advance.