TanStack react table v8 style each cell based on the cell value - reactjs

We are migrating our tables from v7 to v8. And I'm kinda got a problem with cells conditional styling.
So basically what I want to do is, based on a status (which is coming to table data) I need to add a specific className to every cell in a row.
In v7 we used this: https://react-table-v7.tanstack.com/docs/examples/data-driven-classes-and-styles
But in v8 I can't find anything like that....
So far I tried to use meta in column definitions https://tanstack.com/table/v8/docs/api/core/column-def#meta where I can set some values to className property, and use it in my JSX like this:
className={cell.column.columnDef.meta?.className}
But problem is anything I can set to meta are static values. For my case I need to set specific className based on my status value. And seems like in meta we can't access any cell props...
const driverFormatter = ({ row }) => {
const { status } = row.original;
return <span>{status}</span>;
};
const columns: ColumnDef<any,any>[] = [
{
accessorKey: "customerName",
header: "Customer"
},
{
accessorKey: "driver",
header: "Driver",
enableSorting: false,
cell: driverFormatter,
meta: {
className: "disabled",
},
},
...
So is there are any way of achieving that using v8???
Thank you!

Related

How can I get the Material-UI DataGrid to read object data from an array?

I'm currently using Redux to fetch data from an API. I am then using this data to populate a DataGrid component from Material-UI. Below is what the api response looks like:
Below is what I currently have setup for the column definitions:
The DataGrid seems to be able to recognize the id field from the results, as seen below, however, I cannot seem to drill down into attributes to get further details.
I'm looking for a solution that will allow me to display the attribute data, along with the id. All help is appretiated, thank you!
You can use valueGetter:
const columns = [
// ...
{
field: 'attributeName',
headerName: 'Attribute Name',
valueGetter: (params) => {
return params.getValue(params.id, "attributes").name;
}
},
// ...
];
You may also need a sortComparator to handle the sorting of this column.
try something like this to map the data out obviously change around the names as needed
const detailsRows = rows.map((row) => {
return {
id: row.item_id,
model: row.model_no,
title: row.title,
};
and then pass it in to DataGrid like this
<DataGrid rows={detailsRows} columns={props.columns} pageSize={10}/>

React Datagrid with cards instead of columns?

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.

Disable alphabetical sorting in ag-grid using the basic model

I use server side sorting with ag-grid. So far I used the enableServerSideSorting property set to true. But after version upgrade this property is not available.
I use the onSortChanged event to capture the sort state of the grid. And I want to handle this sorting on the server side. So ag-grid only display the data in the original order as it comes from the server. Now I sort the data outside the grid and then ag-grid sorting again alphabetically.
I created an example for this. There are two component property setSortParams where I set the sorting and data where I get the data already sorted.
How can I prevent the double sorting?
const ExternalGrid = ({ data, setSortParams }) => {
const gridOptions = {
columnDefs: [
{
headerName: "Quantity",
field: "quantity",
sortable: true
}
],
defaultColDef: {
sortable: true
}
};
const onSortChanged = params => {
const sortModel = params.api.getSortModel();
setSortParams([
sortModel.length > 0,
sortModel.length > 0 ? sortModel[0].sort === "desc" : false
]);
};
return (
<div
className="ag-theme-balham"
style={{
height: "180px",
width: "300px"
}}
>
<AgGridReact
gridOptions={gridOptions}
modules={AllCommunityModules}
onSortChanged={onSortChanged}
rowData={data}
/>
</div>
);
};
example: https://codesandbox.io/s/ag-grid-server-side-sorting-chy7j
You can see in the example, that I display the data under the table. My goal is that it has the same order in the table whatever order I set clicking on the table header.
if you implement the following comparator in every column definition, the grid will not modify the row order when it sorts:
columnDefs: [
{
headerName: "Quantity",
field: "quantity",
sortable: true,
comparator: (valueA, valueB, nodeA, nodeB, isInverted) => 0
}
],
https://codesandbox.io/s/ag-grid-server-side-sorting-fmmgf
While working with server side row model, you should not assign the rowData directly (rowData={data}). Instead, create ServerSideDatasource. When you sort on any column, you will be able to get details as parameters for getRows method.
You could use it to provide sorting info to the server.
Reference: Implementing the Server-side Datasource
Have a look at this plunk: https://plnkr.co/edit/z8KzsZ8sAcCe9tYWJedS?p=preview.
When you sort on a column, observe that you get the details by params.request.sortModel inside dataSource.getRows method.
[{
colId: "athlete"
sort: "asc"
}]

Dynamically show/hide columns based on user selection with respect to react-table : React+Typescript

I am using react-table for as a data grid for an application . I have this scenario where I need to show/hide columns that are listed and based on user selection I need to show/hide them . Is there any way I can achieve this?
Basically need to have a some settings kind of icon , on click of the same I need to display all the available columns and based on the checkbox selection I need to show/hide them.
How can I get all the column values from react-table to show in this dropdown?
How can I add this settings icon as a part of column header(I will be displaying id's under this column), But the header for this column would be a settings icon next to "Edit" label
import * as React from 'react';
import ReactTable from 'react-table';
import 'react-table/react-table.css';
export default class App extends React.Component<{},{}>
constructor(props:any){
super(props);
this.state={
data : [];
}
componentDidMount() {
//using some fetch Call, I get the data and set it to state data property
let data = fetch(); // fetch call which is not described here
this.setState({data})
}
render(){
<ReactTable
data={this.state.data}
columns = {[
{
Header: "Edit",// here i need to add an settings icon next to "Edit" header and on click of the same need to show all the column names, then show/hide them based on selection
id: "row",
Cell: (row:any) => {
return <span>{row.index+1}</span>;
}
},
{
id: 'name,
Header: 'Name',
accessor: 'username',
},
{
id: 'dob,
Header: 'DOB',
accessor: 'userDOB',
},
{
id: 'status',
Header: 'Status',
accessor: 'userStatus',
}
]}
/>
}
}
The first issue I see is you are planning to store all column names in a Row 'Edit' -but the function
'(row:any) => { return {row.index+1}; }' is will iterate over data object - not columns object. That means, if data rows more then columns you are unnecessarily going over all the data rows.
Instead, store columns object state in React State. Update 'show' property of the columns to hide/show columns.
Something like this code here --
https://eim52.codesandbox.io/
This is a super low tech solution that I figured out, and not doing things dynamically, but perhaps this can help you achieve your goal:
To hide a column in a static way do the following:
1) Give the column a value of hidden, which will hide the column but not the column header.
2) Give the column an empty name or else you will see text in the header.
3) Give the column a width of -1. A width of 0 leaves a small empty header column, but -1 'hides' it apparently. Not sure why it works, im not a css master, but it works.
const columnTemplate = [
{
{
key: "costCenter",
name: "",
width: -1,
hidden: true
}
}
];

How can I set default sorter and filters on antd table components?

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.

Resources