row inside a cell - javascript

I have the following simple code that generates the location of various records in a table.
return (
<TableRow>
<TableCell >
// some code_1
</TableCell>
<TableCell >
// some code_2
</TableCell>
<TableCell>
<TableRow> // here I get warning
<TableCell>
// some code_3
</TableCell>
</TableRow>
<TableRow>
<TableCell >
// some code_4
</TableCell>
</TableRow>
<TableRow>
<TableCell >
// some code_5
</TableCell>
</TableRow>
</TableCell>
<TableCell
// some code_6
</TableCell>
</TableRow >
);
And as you can guess, when I add more components to the TableCell (in my case I add TableRow ), I get a warning:
Warning: validateDOMNesting(...): tr cannot appear as a child of td.
Tell me how to save this table structure, get rid of warnings

Copied from my comment above:
You can put table rows inside your cells but not directly. They need to be wrapped in their own seperate inner table element. In the rendered html it will look something like ... > td > table > tbody > tr > td > ...
In this examble I have wrapped your table rows in tables with table body elements, but you may want to wrap the top row in a table head element, <TableHead> instead and subsequently the rest in a table body.
Table head and body may not be required so you can try to place the rows directly inside the table element.
Here is the documentation from Material UI https://mui.com/material-ui/react-table/
return (
<TableRow>
<TableCell>
// some code_1
</TableCell>
<TableCell>
// some code_2
</TableCell>
<TableCell>
<Table>
<TableBody>
<TableRow>
<TableCell>
// some code_3
</TableCell>
</TableRow>
<TableRow>
<TableCell>
// some code_4
</TableCell>
</TableRow>
<TableRow>
<TableCell>
// some code_5
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableCell>
<TableCell>
// some code_6
</TableCell>
</TableRow>
);

Related

When I render a button inside a material-ui table, the button is not clickable

My table looks as such:
<TableContainer component={Paper} style={{height: "40vh", width: "90vh"}}>
<Table size="small" sx={{ minWidth: 200 }}>
<TableHead>
<TableRow>
<TableCell align="center" width="90"></TableCell>
{consequences_description.map((description) => (
<TableCell align="center" width="90">{description}</TableCell>
)
)}
</TableRow>
</TableHead>
<TableBody>
{risk_matrix.map((row, row_index) => (
<TableRow
key={row_index}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{likelyhood_description[row_index]}
</TableCell>
{row.map( (column, column_index) => (
<TableCell align="center">
<ToggleButton
risk={column}
row_index={row_index}
column_index={column_index}
/>
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
The button inside the table is called <ToggleButton/> and it looks as such:
<ThemeProvider theme={filtersTheme}>
<Button variant="contained" color={handleColor()} onClick={console.log("Clicked")} >{risk}</Button>
</ThemeProvider>
As soon as the table renders, the console shows "Clicked", meaning the onClick function gets called for the button as soon as it renders inside the table for some reason, but I am not able to click it and fire the onClick function. Is there a way to do this?
Try to call the onClick function like this:
onClick={() => { console.log('Clicked');

Can not render Table correctly in React

I'm trying to make a table with Material UI in React like that:
Here is my code:
return (
<>
<div className="main-wrapper">
<TableContainer component={Paper}>
<Table style={{ minWidth: '650px' }} aria-label="caption table">
<caption>Test</caption>
<TableHead>
<TableRow>
<TableCell align="left" colSpan={1}>
Something else
</TableCell>
<TableRow align="center">
{daysMaps.map(day => (
<TableCell align="center" colSpan={90}>
{day}
</TableCell>
))}
</TableRow>
<TableRow align="center">
{daysMaps.map(() => {
{shifts.map(shift => {
<TableCell align="center">
{shift}
</TableCell>
})}
})}
</TableRow>
</TableRow>
</TableHead>
</Table>
</TableContainer>
</div>
</>
);
I just write the Table Head codes here.
These are the problems:
The shifts(morning, noon, night) doesn't appear on the page
A warning is shown on the console: Warning: validateDOMNesting(...): <tr> cannot appear as a child of <tr>.
How can I fix this problem and make a correct table?
You somehow mixed up the code and forgot the return statements:
<TableRow align="center">
{daysMaps.map(() => {
return shifts.map(shift => {
return <TableCell align="center">{shift}</TableCell>;
});
})}
</TableRow>
Alternatively, exchange the curly braces with round ones, then you can omit the return statement. I made a small codepen for you.
The warning seems to be related to the way material-ui renders the table.
I suspect you can't put TableRow inside a TableRow tag.
You'll need to use rowpspan somewhere. This is a guess, but perhaps like this:
return (
<>
<div className="main-wrapper">
<TableContainer component={Paper}>
<Table style={{ minWidth: '650px' }} aria-label="caption table">
<caption>Test</caption>
<TableHead>
<TableRow>
<TableCell align="left" colSpan={1} rowSpan="2">
Something else
</TableCell>
{daysMaps.map( (day, i) => (
<TableCell key={i} align="center" colSpan={3}>
{day}
</TableCell>
))}
</TableRow>
<TableRow>
{daysMaps.map(() => {
{shifts.map( (shift,i) => (
<TableCell key={i} align="center">
{shift}
</TableCell>
))}
})}
</TableRow>
</TableHead>
</Table>
</TableContainer>
</div>
</>
);
I've added key attributes in for you. You'll get an error without those,
this error means you cannot put a <tr> tag as a child of <tr> nor <td> as a child of <td>
change your code to this
<TableHead>
<TableRow>
<TableCell align="left" colSpan={1}>
Something else
</TableCell>
<TableCell align="center">
{daysMaps.map(day => (
<span style={{textAlign:"center"}}>
{day}
</span>
))}
</TableCell>
<TableCell align="center">
{daysMaps.map(() => { {shifts.map(shift => {
<span style={{textAlign:"center"}}>
{shift}
</span>
})} })}
</TableCell>
</TableRow>
</TableHead>

display an full-width row in material-ui table react

I want to display some data in a table this is my JSX code:
const StudentsTable = (props) => {
const classes = useStyles();
return (
<TableContainer component={Paper}>
<Table className={classes.table} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>NR.</TableCell>
<TableCell align="right">NUME</TableCell>
<TableCell align="right">E-MAIL</TableCell>
<TableCell align="right">NR.TELEFON</TableCell>
<TableCell align="right">CLASA</TableCell>
<TableCell align="right">ACTIUNI</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.students.length > 0 ? (
props.students.map((student, i) => (
<TableRow key={student.studentName}>
<TableCell component="th" scope="row">
{i + 1}
</TableCell>
<TableCell align="right">{student.studentName}</TableCell>
<TableCell align="right">{student.studentEmail}</TableCell>
<TableCell align="right">{student.studentPhone}</TableCell>
<TableCell align="right">{student.clasa}</TableCell>
<TableCell align="center" className={classes.actionsCell}>
<BootstrapButton variant="primary" size="sm">
EDITARE
</BootstrapButton>
<BootstrapButton
variant="danger"
size="sm"
onClick={() => props.deleteStudent(student.studentName)}
>
STERGERE
</BootstrapButton>
</TableCell>
</TableRow>
))
) : (
<Typography variant="h5">
NU EXISTA ELEVI ADAUGATI.{"\n"} PUTETI ADAUGA APASAND PE BUTONUL
"ADAUGA ELEVI"
</Typography>
)}
</TableBody>
</Table>
</TableContainer>
);
};
when the props.students it's an empty array I want to return a single full-width row with this message: NU EXISTA ELEVI ADAUGATI.{"\n"} PUTETI ADAUGA APASAND PE BUTONUL "ADAUGA ELEVI" but in my app, the table looks something like this:
how to fix it?
In the place where you want to render a full row
use
<TableRow><TableCell colSpan={6}>"your message"</TableCell></TableRow>

How to merge React TableCells inside a map function?

So I am trying to create a table with material-ui where rows of w1 and w2 are merged vertically, but I can't seem to find a solution. Using rowSpan when hardcoding table manually works just fine, but when I use it inside map function it creates 4 columns with merged rows of the same element. I need to map data because there is going to be lots of rows in that table and hardcoding all rows is not reasonable.
Any type of suggestion to resolve this?
<TableBody>
{data.data.map((row, i) => (
<TableRow key={row.i}>
<TableCell className={classes.fontEditable} component="th" scope="row">
{row.x1}
</TableCell>
<TableCell className={classes.fontEditable} align="right">
{row.x2}
</TableCell>
<TableCell rowSpan={4} className={classes.fontEditable} align="right">
{row.w1}
</TableCell>
<TableCell rowSpan={4} className={classes.fontEditable} align="right">
{row.w2}
</TableCell>
<TableCell className={classes.font} align="right">
{row.t}
</TableCell>
</TableRow>
))}
</TableBody>
Expected outcome
Actual outcome
problem:
it creates the w1 and w2 cell in each row because of the map function
solution:
you can do an if condition for the w1 and w2 print for the first only as the following
<TableBody>
{data.data.map((row, i) => (
<TableRow key={row.i}>
<TableCell className={classes.fontEditable} component="th" scope="row">
{row.x1}
</TableCell>
<TableCell className={classes.fontEditable} align="right">
{row.x2}
</TableCell>
{i === 0?
<TableCell rowSpan={4} className={classes.fontEditable} align="right">
{row.w1}
</TableCell>
<TableCell rowSpan={4} className={classes.fontEditable} align="right">
{row.w2}
</TableCell>
:null}
<TableCell className={classes.font} align="right">
{row.t}
</TableCell>
</TableRow>
))}

Nested Material UI Dialog with Table not rendering

I have a component that renders a fullscreened <Dialog> with a <Table>.
Every row in this <Table> contains a <TableCell>, which contains a <Button> component.
When pressed, another, not fullscreened <Dialog> containing a <Table> should pop up and show what the object in the main <Table> contains.
Something like this:
---Basket---Total---Products----Date-----
-------A---------3------------[1]------someDate-- // [1] being the button
onClick() of [1] triggers the smaller <Dialog>
---Name---Price---Quantity---
----Prod-------3----------1------- // Nested <Dialog>
Now, I have a method that just parses the date I get from the backend into the Date column in the main <Table>.
Funnily, if I press the <Button> for the second, smaller <Dialog>, the method gets called again, everything freezes for 5 seconds and a bunch of windows pop up over each other.
I have my open variable in the state, so I thought that the whole thing gets rerenderer when I toggle it. Which would make sense.
I tried using <Modal> which would actually be a better option, but it just crashes Chrome. Screen becomes black with parallel lines across.
So, basically, I'm doing two loops in the <Dialog> component.
Here's the code using <Dialog>:
<Dialog
open={this.props.loadBasketsWindowOpen}
transition={Transition}
keepMounted
onClose={this.handleClose}
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description"
fullScreen
>
<DialogTitle id="alert-dialog-slide-title">
<p style={centerDiv}>{"Baskets: "}{this.props.openBaskets.length}</p>
<hr style={horizontalLineStyle}/>
</DialogTitle>
<DialogContent>
<div style={centerDiv}>
<Table>
<TableHead>
<TableRow>
<TableCell style={tableTextStyle}>User</TableCell>
<TableCell style={tableTextStyle}>Total</TableCell>
<TableCell style=tableTextStyle}>Products</TableCell>
<TableCell style={tableTextStyle}>Date</TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.props.baskets !== undefined ?
this.props.baskets.map(basket => {
return(
<TableRow key={basket.id}>
<TableCell style={tableTextStyle}>
{basket.user}
</TableCell>
<TableCell style={tableTextStyle}>
€{basket.total}
</TableCell>
<TableCell style={tableTextStyle}>
<Button onClick={this.onToggle}>
{basket.posBasketItems.length}
<Dialog
open={this.state.innerTableWindowOpen}
onClose={this.handleClose}
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-
description"
>
<DialogTitle>
<p style={centerDiv}>
{"Cart: "}
{basket.length} Products
</p>
<hr style={horizontalLineStyle}/>
</DialogTitle>
<DialogContent>
<Table>
<TableHead>
<TableRow>
<TableCell>
Name
</TableCell>
<TableCell>
Price
</TableCell>
<TableCell>
Quantity
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{basket.items.map(item => {
return (
<TableRow key={item.id}>
<TableCell>
{item.name}
</TableCell>
<TableCell>
{item.price}
</TableCell>
<TableCell>
{item.quantity}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</DialogContent>
</Dialog>
</Button>
</TableCell>
<TableCell>
{this.parseDate(basket.date)}
</TableCell>
<TableCell>
<Button
onClick={()=>this.setToCurrentBasket(basket)}
>
<ADD_TO_SHOPPING_CART />
</Button>
</TableCell>
</TableRow>
);
}) : ''}
</TableBody>
</Table>
</div>
</DialogContent>
<DialogActions>
<div>
<MuiThemeProvider theme={cancelButtonTheme}>
<Button
variant="raised"
onClick={this.closeOpenBasketsWindow}
color="secondary"
>
CANCEL
</Button>
</MuiThemeProvider>
</div>
</DialogActions>
</Dialog>
Here's onToggle() and the state
state = {
innerTableWindowOpen: false
};
onToggle = () => {
this.setState({
innerTableWindowOpen: !this.state.innerTableWindowOpen
});
}
I would appreciate any idea to fix this with <Dialog> or <Modal> or even something similar.
The idea is to have a short preview of what's in the basket before choosing one.
Thanks!

Categories