How to make TableCell with full Table width with MaterialUI in React? - reactjs

I got a table, which is looking like this:
import { Typography, Table, TableHead, TableRow, TableCell, TableBody } from '#material-ui/core';
const Example = () => {
return (
<>
<Table>
<TableHead>
<TableRow>
<TableCell align="center"><Typography> 1 </Typography></TableCell>
<TableCell align="center"><Typography> Some </Typography></TableCell>
<TableCell align="center"><Typography> Some</Typography></TableCell>
<TableCell align="center"><Typography> Some </Typography></TableCell>
<TableCell align="center"><Typography> Some </Typography></TableCell>
</TableRow>
</TableHead>
<TableBody>
{
// Here I'm loading some async data
// Meanwhile it's fetching I want to display some loading indicator
}
</TableBody>
</Table>
</>
)
}
And in the TableBody before I display a normal TableRows with data I want to display to users loading indicator that is in the middle of the table. So basically I need one TableCell inside this table that is taking all the columns width, so then I will be able to center my indicator.
How can I achieve that using MaterialUI Components and their API to make my table look like this:

You can expand the cell which you want to include the loading indicator like the following.
Table DOM structure should be considered.
<Table>
<TableHead>
{
!isLoaded
? <TableRow>
<TableCell
colSpan={5} // it seems each line has 5 table cells
align="center"
>
<LoadIndicator />
</TableCell>
: <TableBody>
...
}
Using component props.
<Table component="div">
<TableHead component="div" />
{
!isLoaded
? <LoadIndicator>
: <TableBody component="div">
...
}
...

Related

Where am I missing a key prop here? I'm generating uuids for TableCell keys and I'm using row.id for the row keys

I have this bit of code where I'm getting the warning:
Each child in a list should have a unique "key" prop. Check the render
method of AllPersonnel... at TableRow
And the table cells are not rendering. Any help would be appreciated. Thanks!
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow key={uuidv4()}>
{cols.map((col) => {
return <TableCell key={col.path}>{col.name}</TableCell>
})}
</TableRow>
</TableHead>
<TableBody>
{personnel.map((row, i) => {
return (
<TableRow key={row.id}>
<TableCell key={uuidv4()}>{row.first_name}</TableCell>
<TableCell key={uuidv4()}>{row.last_name}</TableCell>
<TableCell key={uuidv4()}>{row.section}</TableCell>
<TableCell key={uuidv4()}>{row.role}</TableCell>
<TableCell key={uuidv4()}>{row.employee_type}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
You don't need a key on your TableRow, only on the first child in the return of an iterator.
Try :
{personnel.map((row, i) => {
const key = uuidv4()
return (
<TableRow key={key}>
<TableCell>{row.first_name}</TableCell>
...
Normaly...

How to get the value of clicked cell in React Material Table?

I am trying to get the corresponding value of cell in React Material UI Table Component.
I was looking for already predefined component api properties but couldn't find anything appropriate.
Working with Material UI DataGrid component, I achieved that, getting the selected row via onSelectionModelChange thanks to this answer.
But in this case, Table doesn't have any checkboxes and I need to retrieve the data by clicking.
Here is the codesandbox link and the example code:
import * as React from "react";
import Table from "#mui/material/Table";
import TableBody from "#mui/material/TableBody";
import TableCell from "#mui/material/TableCell";
import TableContainer from "#mui/material/TableContainer";
import TableHead from "#mui/material/TableHead";
import TableRow from "#mui/material/TableRow";
import Paper from "#mui/material/Paper";
export default function BasicTable({ users }: any) {
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>userId</TableCell>
<TableCell align="right">id</TableCell>
<TableCell align="right">Title</TableCell>
</TableRow>
</TableHead>
<TableBody>
{users &&
users.map((user: any) => (
<TableRow
key={users.id}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableCell align="right">{user.userId}</TableCell>
<TableCell align="right">{user.id}</TableCell>
<TableCell align="right">{user.title}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
Any help will be appreciated.
You can create an onClick function on the cells that you want this behavior to happen. Assuming that you want this on user.title cells and using console.log as example:
<TableCell align="right" onClick={({target}) => console.log(target.textContent)}>{user.title}</TableCell>
Since you are mapping over your data, you can simply use the desired data from the map:
{users &&
users.map((user: any) => (
<TableRow
key={user.id}
onClick={() => console.log(user.id)} // set desired state here
>
<TableCell align="right">{user.userId}</TableCell>
<TableCell align="right">{user.id}</TableCell>
<TableCell align="right">{user.title}</TableCell>
</TableRow>
))}

How to put Link from react router dom inside Material UI table

Like the title says I need to put Link inside the table from Material UI, but i get these two errors <td> cannot appear as a child of <a> <a> cannot appear as a child of <tr>. Now obviously I know what these two error messages mean, but I need to put Link as let's say container around cells, because I need to be able to click anywhere inside the row for redirection to another page.
Here is my code:
<TableRow key={index}>
<Link
to={`/edit/${apiData.id}/${apiData.name}/${apiData.email}`}
>
<TableCell align="left" style={{ paddingLeft: 40 }}>
{apiData.name}
</TableCell>
<TableCell align="left">{apiData.email}</TableCell>
<TableCell align="left">{apiData.status}</TableCell>
<TableCell align="left">{roles}</TableCell>
</Link>
<TableCell align="right" style={{ paddingRight: 40 }}>
<RoleButton onClick={handleRoleChange}>
{roles === "Admin" ? "Set as User" : "Set as Admin"}
</RoleButton>
</TableCell>
</TableRow>
Anyone know how to fix this, if You do I would greatly appreciate that
You can use onClick in TableRow.
function HomeButton() {
let history = useHistory();
function onRowClick(name) {
history.push(`/user/${name}`);
}
return (
<Table>
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Age</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow onClick={() => onRowClick('tom')}>
<TableCell>Tom</TableCell>
<TableCell>26</TableCell>
</TableRow>
</TableBody>
</Table>
);
}

Material Table - nested columns

Is it possible to make a table with nested columns using material-table library?
Final result that I want to achieve
Yes its possible with material-table . You have to use Components property to achieve that.
function App() {
const columns = [...];
const data = [...];
return (
<div className="App">
<MaterialTable
columns={columns}
data={data}
components={{
Header: props => {
return (
<TableHead>
<TableRow>
<TableCell colSpan={2} align="center">
Average A
</TableCell>
<TableCell colSpan={2} align="center">
Average B
</TableCell>
</TableRow>
<TableRow>
<TableCell align="center">Lower</TableCell>
<TableCell align="center">Upper</TableCell>
<TableCell align="center">Lower</TableCell>
<TableCell align="center">Upper</TableCell>
</TableRow>
</TableHead>
);
},
Row: ({ data }) => {
return (
<TableRow>
<TableCell align="center">{data.lowerA}</TableCell>
<TableCell align="center">{data.upperA}</TableCell>
<TableCell align="center">{data.lowerB}</TableCell>
<TableCell align="center">{data.upperB}</TableCell>
</TableRow>
);
}
}}
/>
</div>
);
}
DEMO: Codesandbox link
You can use colspan. Check example here.
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_td_colspan

How to set image for a column of table with TableCell

I use material-ui to build a table with a column containing image.
My code as below, but the images don't display.
<TableBody>
{data.map(n => (
<TableRow key={n.id}>
<TableCell component="th" scope="row">
{n.first_name}
</TableCell>
<TableCell>{n.last_name}</TableCell>
<TableCell><image src={n.avatar}></image></TableCell>
</TableRow>
))}
</TableBody>
Are you using HTML image tag or material-ui image component? If it is HTML image tag, it should be <img src={n.avatar} /> not <image src={n.avatar}></image>!

Resources