Can you add a button inside a custom TableCell in material UI? - reactjs

Currently, I am creating a table with material-ui, and the last column of the TableHead should contain an upload button. Something like this:
image
I have tried the following:
const StyledTableCell = withStyles((theme) => ({
head: {
color: theme.palette.text.dark,
backgroundColor: theme.palette.success.light,
},
body: {
fontSize: 14,
}
}))(TableCell);
return (
<TableContainer component={Paper}>
<Table>
<TableHead>
<StyledTableRow>
<StyledTableCell align="left">Position</StyledTableCell>
<StyledTableCell align="right">Defect Type by Worker</StyledTableCell>
<StyledTableCell align="right">Tool Decision by Worker</StyledTableCell>
<StyledTableCell align="center">
<Button variant="contained" color="primary">
Upload
</Button>
</StyledTableCell>
</StyledTableRow>
</TableHead>
<TableBody>
...
</TableBody>
</Table>
</TableContainer>
But react will not render if you directly add a button component inside a custom tablecell. Is there a way to add a button inside a custom tablecell? Thank you.

I try your code and because you didn't provide the StyledTableRow code so I change it to TableRow and the button is working fine.
So maybe your problem is in the StyledTableRow, you can try my code like below:
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<StyledTableCell align="left">Position</StyledTableCell>
<StyledTableCell align="right">Defect Type by Worker</StyledTableCell>
<StyledTableCell align="right">Tool Decision by Worker</StyledTableCell>
<StyledTableCell align="center">
<Button variant="contained" color="primary">
Upload
</Button>
</StyledTableCell>
</TableRow>
</TableHead>
</Table>
</TableContainer>

Related

Display Fetched Data from API in react and display in responsive table?

I try to make a responsive table to display fetched data from API in react.js.
I designed a table but it is not responsive.
<TableContainer >
<Table aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell align="right">Name</StyledTableCell>
<StyledTableCell align="right">Photo</StyledTableCell>
<StyledTableCell align="right">Price</StyledTableCell>
<StyledTableCell align="right">Quentity</StyledTableCell>
<StyledTableCell align="right">Sold</StyledTableCell>
<StyledTableCell align="right">Supplier</StyledTableCell>
<StyledTableCell align="right">Manage</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{myproducts.map(product=>
<StyledTableRow >
<StyledTableCell align="right">{product.name}</StyledTableCell>
<StyledTableCell align="right"><img className='tableimage' src={product.img} alt="" /></StyledTableCell>
<StyledTableCell align="right">{product.price}</StyledTableCell>
<StyledTableCell align="right">{product.quantity}</StyledTableCell>
<StyledTableCell align="right">{product.sold}</StyledTableCell>
<StyledTableCell align="right">{product.supplier}</StyledTableCell>
<StyledTableCell align="right">
<div class="col-sm">
<button onClick={() => navigateToProductDetail(product._id)} className='btn btn-dark text-light border-light rounded-0 '>
<FontAwesomeIcon icon={faPenSquare} /></button>
<button onClick={() => handleDelete(product._id)} className='btn btn-dark border-light text-light rounded-0'>
<FontAwesomeIcon icon={ faTrash} /></button>
</div>
</StyledTableCell>
</StyledTableRow>
)}
</TableBody>
</Table>
</TableContainer>
this table is designed with material UI to display API fetch data but this table is not responsive.It only display the fetch data.

Disable Table pagination in material-ui Reactjs

How to hide table pagination in material-UI if the data is empty array ?I couldn't find props that will hide it from documentation of table pagination in reactjs?
pagiantion
Try below solution
<TableContainer component={Paper}>
<Table className={classes.table} aria-label="custom pagination table">
<TableBody>
{rows.map((row) => (
<TableRow key={row.name}>
<TableCell component="th" scope="row"></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
))}
</TableBody>
// Add below condition to hide pagination when no rows are there
{
rows.length > 0 && (
<TableFooter>
<TableRow>
<TablePagination
.....
.....
.....
.....
.....
/>
</TableRow>
</TableFooter>
)
}
</Table>
</TableContainer>

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 UI, Warning <td> cannot appear as a child of <div>

I'm using React, typescript and Material UI. I've created a pretty common "Create user form" with basic inputs for username, name, email, ect. Added two buttons, "Edit" and "Delete." Everything seems to function properly, however, I cannot get this error message resolved.
Warning: validateDOMNesting(...): <td> cannot appear as a child of <div>.
Here's the table from a react component:
<TableContainer className={classes.scroll} component={Paper}>
<Table stickyHeader aria-label="table">
<TableHead>
<TableRow>
<TableCell>Username</TableCell>
<TableCell align="right">First name</TableCell>
<TableCell align="right">Last name</TableCell>
<TableCell align="right">Email</TableCell>
<TableCell align="right">Connect_username</TableCell>
<TableCell align="right">Role</TableCell>
<TableCell align="left">Edit</TableCell>
<TableCell align="left">Delete</TableCell>
</TableRow>
</TableHead>
<TableBody>
{(rowsPerPage > 0
? props?.items.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
: props?.items
).map(item => (
<TableRow key={item.user_id}>
<TableCell component="th">{item.username}</TableCell>
<TableCell align="right">{item.first_name}</TableCell>
<TableCell align="right">{item.last_name}</TableCell>
<TableCell align="right">{item.email}</TableCell>
<TableCell align="right">{item.connect_username}</TableCell>
<TableCell align="right">{item.role?.map(r=>r.role).join(",")}</TableCell>
<TableCell>
<Button onClick={() => props.handleEdit(item)}>Edit</Button>
</TableCell>
<TableCell>
<Button onClick={() => props.handleConfirmDelete(item.user_id)}>Delete</Button>
</TableCell>
</TableRow>
))}
</TableBody>
<TablePagination
rowsPerPageOptions={[10, 25, { label: 'All', value: -1 }]}
count={props.items.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Table>
</TableContainer>
component={Paper} is likely causing this. Can you try removing it? If you want the table to appear on a Paper component, then try nesting TableContainer under Paper.
put TablePagination in the TableBody tag and wrap it in TableRow.
Had a similar issue and this fixed it.
Like this:
<TableBody>
{(rowsPerPage > 0
? props?.items.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
: props?.items)
.map(item => (
<TableRow key={item.user_id}>
<TableCell component="th">{item.username}</TableCell>
<TableCell align="right">{item.first_name}</TableCell>
<TableCell align="right">{item.last_name}</TableCell>
<TableCell align="right">{item.email}</TableCell>
<TableCell align="right">{item.connect_username}</TableCell>
<TableCell align="right">{item.role?.map(r=>r.role).join(",")}</TableCell>
<TableCell>
<Button onClick={() => props.handleEdit(item)}>
Edit
</Button>
</TableCell>
<TableCell>
<Button onClick={() => props.handleConfirmDelete(item.user_id)}>
Delete
</Button>
</TableCell>
</TableRow>
<TableRow>
<TablePagination
rowsPerPageOptions={[10, 25, { label: 'All', value: -1 }]}
count={props.items.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</TableRow>
))}
</TableBody>
update: "#mui/material": "^5.10.9"
in my case this error was causing TablePagination and not Paper component.
working solution is wrapping pagination not only with row but also footer as follow
<TableContainer component={Paper}>
<Table>
<TableBody>
...
</TableBody>
<TableFooter>
<TableRow>
<TablePagination />
</TableRow>
</TableFooter>
</Table>
</TableContainer>
mui docs: https://mui.com/material-ui/react-table/#custom-pagination-actions

How to create a new table with selected options from a dropdown?

I want to create a new table that is composed of previously selected options from a dropdown menu (Material-UI). Since I'm new to React and Material-UI, I can't figure out how to do this.
There is already a table including a column that contains a dropdown. This dropdown allows to select multiple options.
Component TableInput:
function TableInput() {
return (
<div>
{/* First table with the multiselect-dropdown */}
<Paper>
<Table>
<TableHead>
<TableRow>
<TableCell align="right">Examns</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell align="right">
<ExamInput />
</TableCell>
</TableRow>
</TableBody>
</Table>
</Paper>
{/* Second table that should be rendered according to the selected options in the first table */}
<Paper>
<Table>
<TableHead>
<TableRow>
<TableCell align="right">Exam</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell component="th" scope="row">
{/* Here the selected options from the first table should be listed */}
{/* for example. "Master, Bachelor, PhD" */}
</TableCell>
<TableCell align="right">
{/* Here, another multiselect-dropdown should appear according to the rendered option in the first column
It is used to select the achieved score in the examn
Each examn has a predefined list of score options.*/}
</TableCell>
</TableRow>
</TableBody>
</Table>
</Paper>
</div>
)
}
Component ExamnInput (that is used in TableInput):
function ExamInput() {
const names = ['Abitur', 'Mittlere Reife', 'Master', 'Bachelor']
const [examn, setExamn] = React.useState<string[]>([])
function handleChange(event: React.ChangeEvent<{ value: unknown }>) {
setExamn(event.target.value as string[])
}
return (
<Paper>
<FormControl>
<InputLabel htmlFor="select-multiple">Exams</InputLabel>
<Select
multiple
value={examn}
onChange={handleChange}
input={<Input id="select-multiple" />}
>
{names.map(name => (
<MenuItem
key={name}
value={name}
>
{name}
</MenuItem>
))}
</Select>
</FormControl>
</Paper>
)
}
Furthermore I created a super simple image showing how the whole thing should look.
Thanks so much in advance!

Resources