How to set fixed column headers in react js - reactjs

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} />

Related

React-table not rendering the cell values

Columns are getting rendered but not the cell values, I tried console.log in the component file, it is coming. But why not render in the actual cell
const tableInstance = useTable({ columns, data });
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = tableInstance;
console.log(typeof columns,{columns});
console.log(typeof data,{data});
return (
<div>
<ReactBootStrap.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>
</ReactBootStrap.Table>
</div>
)
Also double checked the accessor with the response, I'm not using one of the columns from the response in my table, is that the reason? Can't figure this out at all

Trying to compare the value of two cells in react, then change style based on value

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.

Changing state value doesn't work properly on react-table

I am trying to add a "delete" button to every row of data using react-table. Button splices the data and removes that line from data when pressed. When the "delete" button is clicked for the first time it works properly. However on the second press nothing happens. For some reason changeData doesn't change the data on the second run. Why this happens?
function DataTable({columns, data_rows}) {
const [data, changeData] = useState(data_rows);
if (columns[0].Header !== "Action") {
columns.unshift({
Header: 'Action'
});
}
columns[0]['columns'] = [{
Header: ' ', Cell: ({row}) => (
<ButtonGroup>
<Button className="button-dark button-sm" onClick={() => {
const dataCopy = [...data];
dataCopy.splice(row.index, 1);
changeData(dataCopy);}}>
Remove
</Button>
</ButtonGroup>
)
}]
const {
getTableProps,
getTableBodyProps,
headerGroups,
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, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
})}
</tr>
);
})}
</tbody>
</table>
);
}

How to pass props to row in react-table

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 />}

REACT: Instead of sorting by clicking a button - sorting by clicking header "id" in table

I make request to server and I get response. Response it data which I display in view table-list. Also now I try implement when I click button changeAsc happen sort by asc-desc.
But I need that sort by asc-desc was happening when I click on header header id in table. And display the word asc or desc to the right of the header id. Table I export in file Home.js from file - Table.js.
What I need to change in file Table.js that implement sort when I click to header id?
Home.js:
import Table from "./Table/Table.js";
const Home = () => {
const [value, setValue] = useState({
listCategory: [],
sortAscDesc: "asc",
});
useEffect(() => {
async function fetchData(sortAscDesc) {
const res = await api('api/categories', sortAscDesc);
/....
}
fetchData(value.sortAscDesc);
}, [value.sortAscDesc]);
const changeSortAscDesc = () => {
setValue((prev) => ({
...prev,
sortAscDesc: prev.sortAscDesc == 'asc' ? 'desc' : 'asc'
}));
};
return (
<div>
<Table dataAttribute={value.listCategory}/>
// I WANT DELETE THIS BUTTON: - BECAUSE I WANT SORT BY HEADER "id"
<button onClick={() => changeSortAscDesc()}>changeAsc</button>
</div>
);
};
Table.js:
export default ({dataAttribute}) => (
<table className="table">
<thead className="table-head">
<tr>
<th>id</th> //I WANT SORT WHEN I CLICK ELEMENT id
<th>title</th>
<th>created_at</th>
</tr>
</thead>
<tbody>
{dataAttribute.map(item => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.title}</td>
<td>{item.created_at}</td>
</tr>
))}
</tbody>
</table>
);
You can try like this:
<Table dataAttribute={value.listCategory} changeSortAscDesc={changeSortAscDesc} />
In your Table.js
export default (props) => (
<table className="table">
<thead className="table-head">
<tr>
<th onClick={props.changeSortAscDesc}>id</th> //I want sort when I click by element id
<th>title</th>
<th>created_at</th>
</tr>
</thead>
<tbody>
{props.dataAttribute.map(item => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.title}</td>
<td>{item.created_at}</td>
</tr>
))}
</tbody>
</table>
);

Resources