I've been following https://blog.logrocket.com/complete-guide-building-smart-data-table-react/. To apply custom styling depending on cell value, I'm updating the column object like so:
return {
Header: key,
accessor: key,
width: "150",
sortType: "basic",
Cell: ({cell: {value} }) => {
if (value == "Error") {
return <RedCell/>
}
...
}
}
Is it possible instead to apply custom styling to the row containing the cell? I guess a prop would have to be passed down to row, but am just not clear at all on how to do this.
Any pointers would be much appreciated.
For anyone stumbling upon this issue, this has been answered by the author of the react-table library here — https://spectrum.chat/react-table/general/v7-row-getrowprops-how-to-pass-custom-props-to-the-row~ff772376-0696-49d6-b259-36ef4e558821
In your Table component, you pass on any prop (say, rowProps) of your choice for rows —
<Table
columns={columns}
data={data}
rowProps={row => ({
onClick: () => alert(JSON.stringify(row.values)),
style: {
cursor: "pointer"
}
})}
/>
Then to actually use this —
function Table({ columns, data, rowProps = () => ({}) }) {
// Use the state and functions returned from useTable to build your UI
const { getTableProps, headerGroups, rows, prepareRow } = useTable({
columns,
data
});
// Render the UI for your table
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render("Header")}</th>
))}
</tr>
))}
</thead>
<tbody>
{rows.map(
(row, i) =>
prepareRow(row) || (
<tr {...row.getRowProps(rowProps(row))}>
{row.cells.map(cell => {
return (
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
);
})}
</tr>
)
)}
</tbody>
</table>
);
}
Currently you are applying styling to your columns definitions.
In order to apply styling to an entire Row. (eg. make the entire row red if value == "Error"), I would do it in your table UI.
In your UI you are going to be calling prepareRow(row) and then using the row to render the cells.
maybe with : row.cells.map
At this point you could do something different based on the content of a cell row.cells[0]
maybe something like this:
{(row.cells[0].value !== "Error" && row.cells.map(cell =>
{
return (
<TableCell {...cell.getCellProps({ className: cell.column.className })}>
{cell.render('Cell')}
</TableCell>
);
})) || <RedRow />}
Related
i have tried in my code to call api and popolate a table with the information taken from that api. In my headers of the column i have setted them with the excact name taken from api, but i want to set them in a different name as i am told to.
For example the first header of the first column will be called: id. The second header will be: description. Third: number. 4th: quontity; 5th ready, 6th: reserved.
THank you guys for your time and for your help.
Here is the code:
function Table({ columns, data }) {
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
useTable({
columns,
data,
});
// Render the UI for your table
return (
<table className="TableStyle" {...getTableProps()}>
<thead className="TableHeder">
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th className="TableHeaderCell" {...column.getHeaderProps()}>{column.render("Header")}</th>
))}
</tr>
))}
</thead>
<tbody className="TableBody" {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr className="TableSingleRow" {...row.getRowProps()}>
{row.cells.map((cell) => {
return <td className="TableCell" {...cell.getCellProps()}>{cell.render("Cell")}</td>;
})}
</tr>
);
})}
</tbody>
</table>
);
}
The second part will be:
// this will run evertime one of the following state will change => data, currentPage, dataPerPage
useEffect(() => {
// generate dynamically columns from first object from array
setColumns(
Object.keys(data[0] || []).map((key) => ({
Header: key,
accessor: key,
}))
);
filterData();
}, [data, currentPage, dataPerPage]);
The last part which will be the return :
<Table columns={columns} data={currentData} />
I'm new to react table, I've created the basic table using react-table. I'm not able to figure out how to change the color of a cell when click on that particular cell. I don't find any resource or related question on Stackoverflow.
Here is my Code looks like:
import React, { useMemo } from 'react'
import { useTable } from 'react-table'
import MOCK_DATA from '../MOCK_DATA.json'
import { COLUMN } from './Column'
import './table.css'
export const BasicTable = () => {
const columns = useMemo(() => COLUMN, [])
const data = useMemo(() => MOCK_DATA, [])
const {
getTableProps,
getTableBodyProps,
headerGroups,
footerGroups,
rows,
prepareRow
} = useTable({
columns,
data
})
return (
<>
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
<tfoot>
{footerGroups.map(footerGroup => (
<tr {...footerGroup.getFooterGroupProps()}>
{footerGroup.headers.map(column => (
<td {...column.getFooterProps()}>{column.render('Footer')}</td>
))}
</tr>
))}
</tfoot>
</table>
</>
)
}
I'm getting demo data in MOCK_DATA(it's just random data). When I click on particular cell I want that particular cell color change. How I should approach this. In react if we want to change color of button or anything else we can use useState to do that but I'm not able to figure out here.
Here is the live example: https://codesandbox.io/s/focused-field-2sgkqz?file=/src/MOCK_DATA.json:35842-48670
you want is:when you click a particular cell,that particular cell change color?
if so, you just need remember the selected row.like is demo, is this you want ?
Inactive State:
Active State:
When I toggle a single button the state of every other button changes which I don't want. Is there any way to control the state of these toggles individually
This is my code for columns to be used in the table:
const COLUMNS = useMemo (() => [
{
Header: "Username",
accessor: "Username",
textAlign: "left",
sortable: false,
},
{
Header: "Status",
accessor: "Status",
textAlign: "center",
Cell: ({ value, cell: { row } }) => (
<div>
<FormControlLabel
control={
<IOSSwitch
checked={status}
onClick={toggler}
name="status"
/>
}
/>
{status ? <span>Active</span> : <span>Inactive</span>}
</div>
),
},
This is my code for the table:
<Table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<Th
{...column.getHeaderProps({
style: { textAlign: column.textAlign },
})}
>
{column.render("Header")}
</Th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row) => {
prepareRow(row);
return (
<Tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<Td
{...cell.getCellProps({
style: { textAlign: cell.column.textAlign },
})}
>
{cell.render("Cell")}
</Td>
);
})}
</Tr>
);
})}
</tbody>
</Table>
You have to assign each button to its individual state for example you can have three states for three buttons.
your states should look like this:
const [firstButton, setFirstButton] = useState(false)
const [secondButton, setSecondButton] = useState(false)
const [thirdButton, setThirdButton] = useState(false)
and in your onClicks you should say:
for example for second button:
onClick={()=>setSecondButton(false)}
and when you want to use this state in your table you should match every button with its state
ps: if your number of buttons are not fix, you should write a function to return an object which keys are button names and values are false ( false is default and this should change when clicks ).
Because of the immutability of states in react.js, you should clone the state and change what you want and leave every other thing as it is then update the whole state.
and use it like:
onClick={()=>setButtonsState({...buttonsState, secondButton:false})}
where buttonsState is like:
const [buttonsState, setButtonsState] = useState(
{
firstButton: false,
secondButton: false,
thirdButton: false
}
)
I am new to react.
I made a table using react-table module I'm trying to highlight all the cells where the cell in the first column doesn't equal the cell next to it in column 2.
here is my table component:
const Table = () => {
const columns = useMemo(() => Columns, [])
const data = useMemo(() => mock, [])
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
state,
setGlobalFilter,
} = useTable({
columns,
data,
}, useGlobalFilter)
const { globalFilter } = state
return (
< >
<SearchBar searchValue={globalFilter} setSearchValue={setGlobalFilter}/>
<div>
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) =>(
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps()}>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{
rows.map((row) =>{
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell, index)=> {
return <td {...cell.getCellProps()} style = {{
backgroundColor:{rows[0].cells[index].value!==rows[1].cells[index].value ? 'red': null}
}}>{cell.render('Cell')}</td>
})}
</tr>
)
})
}
</tbody>
</table>
</div>
</>
)
}
export default Table
when I run this I get two errors
expected ',' at
backgroundColor:{rows[0].cells[index].value!==rows[1].cells[index].value
? 'red': null}
expected ':' at
backgroundColor:{rows[0].cells[index].value!==rows[1].cells[index].value
? 'red': null}
any help would be really appreciated
{backgroundColor:(rows[0].cells[index].value!==rows[1].cells[index].value ? 'red': null)}
use parentheses not braces.
All the examples on the internet are using old-style > component, I could not found any example for showing how to handle row_click event.
I tried my below example but no luck.
It won't be stopped by const onRowClick = (state, rowInfo, column, instance) => { as it's supposed to be.
import React from 'react'
import {useTable, useSortBy, useTableState, usePagination} from 'react-table'
function Table({getTrProps, columns, data}) {
const tableState = useTableState({pageIndex: 2})
const {
getTableProps,
getTrProps,
....
state: [{pageIndex, pageSize}],
} = useTable(
{
getTrProps,
columns,
data,
state: tableState,
},
useSortBy,
usePagination
)
// Render the UI for your table
return (
<>
<table {...getTableProps()}
className="table table-bordered"
>
<thead>
{headerGroups.map((headerGroup): any => (
<tr {...headerGroup.getHeaderGroupProps()}
className={`tx-10 tx-spacing-1 tx-color-03 tx-uppercase`}
>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>{column.render('Header')}
<span>
{(column as any).isSorted
? (column as any).isSortedDesc
? ' 🔽'
: ' 🔼'
: ''}
</span>
</th>
))}
</tr>
))}
</thead>
</table>
</>
)
}
function TransactionTable(props) {
let data = props.data || []
let filter = props.filter || {}
....
const onRowClick = (state, rowInfo, column, instance) => {
return {
onClick: e => {
debugger
}
}
}
return (
<div className={`card card-dashboard-table`}>
<div className="table-responsive">
<Table
getTrProps={onRowClick}
columns={filter.adjustParkingLot ? columns: withouParkingColumns}
data={data}/>
</div>
</div>
)
}
export default TransactionTable
I think you can pass additional props to getRowProps function on row.
You just need to pass an object containing additional props.
For example you can pass style object as this
tr.getRowProps({ style: { color: 'blue' } })
Same way you can pass onClick to getRowProps function.
You can pass the row object to your onClick callback to get the row data
I passed rowInfo callback for getting the row click
Hope this is what you want.
Ref: ReactTable RowProperties