conditional enclosing elements React - reactjs

Having a simple react Component:
<Table>
<TableBody>
<TableCell>
x
</TableCell>
</TableBody>
</Table>
How can I conditionally enclose the TableBody in yet another component (e.g. Paper)? I thought of something like the below, but this does not seem to do it.
<Table>
{paper && <Paper>}
<TableBody>
<TableCell>
x
</TableCell>
</TableBody>
{paper && </Paper>}
</Table>

If you want to avoid repeating the code for the Table body, you can assign it to a variable and use that.
const content = (
<TableBody>
<TableCell>
x
</TableCell>
</TableBody>
);
return (
<Table>
{paper ? <Paper>{content}</Paper> : content}
</Table>
)

You can do it this way. I considered null condition for paper variable, you can do it with any.
<Table>
{paper !== null ? (
<Paper>
<TableBody>
<TableCell>
x
</TableCell>
</TableBody>
</Paper>
):(<TableBody>
<TableCell>
x
</TableCell>
</TableBody>)}
</Table>

Related

React - render functional subcomponent

I am having an issue rendering a React functional component when included as subcompnent in a parent component.
The following renders perfectly:
<Table title="Actions">
<TableHeaderCell>Name</TableHeaderCell>
<TableHeaderCell>Description</TableHeaderCell>
<TableHeaderCell>Start Date</TableHeaderCell>
{data.data.map(item => (
<TableRow>
<TableCell>
{item.name}
</TableCell>
<TableCell>
{item.activity_type.description}
</TableCell>
<TableCell>
{item.startDate}
</TableCell>
</TableRow>))}
</Table>
However, when replacing the TableRow with a functional component, then the TableRow is never shown. I created the following Subcomponent:
export const ActivityRowComponent = props => {
console.log('entered ActivityRowComponent');
const item = props.activityItem;
return (
<TableRow>
<TableCell>
{item.name}
</TableCell>
<TableCell>
{item.activity_type.description}
</TableCell>
<TableCell>
{item.startDate}
</TableCell>
</TableRow>
);
};
ActivityRowComponent.propTypes = {
activityItem: PropTypes.object.isRequired,
};
and changed the code from above to:
<Table title="Actions">
<TableHeaderCell>Name</TableHeaderCell>
<TableHeaderCell>Description</TableHeaderCell>
<TableHeaderCell>Start Date</TableHeaderCell>
{data.data.map(item => (
<ActivityRowComponent key={item.activity_id} activityItem={item} />
))}
</Table>
Note that the "console.log" in "ActivityRowComponent" is never reached. Also, if I set a breakpoint I can observe that "ActivityRowComponent" is never called. And, note that the array data.data has a length of 1.
Any ideas what I am doing wrong? What to do in order for the ActivityRowComponent to be rendered?
I've reproduced your scenario at CodeSandbox using HTML table.
And your component is rendering OK. Changed a bit though.
Please check.

React map over nested array

Im fetching an array of rows from firebase, with each row looking like the one below.
row = [
{
index: 1,
body: 'description'
options: ['option1', 'option2', 'option3']
}
]
I'm currently rendering these rows to a table in React as so:
{this.state.rows.map((row) => (
<TableRow key={row.visit}>
<TableCell align="left">{row.index}</TableCell>
<TableCell align="left">{row.body}</TableCell>
<TableCell align="left">{row.options}</TableCell>
</TableRow>))}
However, I'm trying to get the options to be in a dropdown or similar, so as to look neater and not take up too much vertical space. Is there a way to map through a nested array and output it into a dropdown?
You can also map the nested data. I suggest using a select element.
{this.state.rows.map((row) => (
<TableRow key={row.visit}>
<TableCell align="left">{row.index}</TableCell>
<TableCell align="left">{row.body}</TableCell>
<TableCell align="left">
<select>
{row.options.map((option, i) => (
<option key={i} value={option}>{option}</option>
))}
</select>
</TableCell>
</TableRow>
))}

How to manage noDataComponent or display no rows found in ReactTable V7

I was using the older version of React Table for last couple of months and now when i started using Latest version v7, i started facing difficulty in customizing the table while no data is found in the table to be displayed. It doesn't show any message like 'No Rows Found' which was earlier displayed in previous versions of the table. How could i render the noDataComponent.
As v7 is headless, you are responsible for the output under the varying conditions. You likely have something like map() in place to iterate over the data array similar to:
<TableBody>
{page.map((row) => {
prepareRow(row);
return (
<TableRow {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<TableCell {...cell.getCellProps()}>
{cell.render('Cell')}
</TableCell>
);
})}
</TableRow>
);
})}
</TableBody>
You can add some code to detect the condition where no rows are found similar to:
{page.length === 0 &&
<TableRow>
<TableCell>
No data to display
</TableCell>
</TableRow>
}

Material UI: How do I divide a table into 2 parts?

I want to divide a table into 2 halves using a vertical line(e.g. blue line in the image) such that there are 2 sections of columns. Each section of column can have multiple columns as follows (Please pardon my terrible drawing skills). How can I achieve this using material ui table?
Please help me out. Thanks
What I've tried till now(didnt work):
const tableHeaders = this.getTableHeaders()
const tableRows = this.getTableRows()
return (
<div className='segment-table-container'>
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell />
<TableCell>Field</TableCell>
<Divider orientation='vertical' />
{tableHeaders}
</TableRow>
</TableHead>
<TableBody>
{tableRows}
</TableBody>
</Table>
</TableContainer>
</div>
)

How to add an element to Material-UI TablePagination?

I'm using Material-UI Table with TablePagination in my project. This is how it appears:
Now I want the pagination to be aligned to left instead of right, and on the left I want to add another element, for example Button.
I was able to move the alignment to left by restyling the .spacer element. Here's my code:
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
colSpan={3}
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
SelectProps={{
native: false,
}}
onChangePage={this.handleChangePage}
onChangeRowsPerPage={this.handleChangeRowsPerPage}
ActionsComponent={TablePaginationActions}
classes={{spacer: classes.paginationSpacer}} >
</TablePagination>
</TableRow>
</TableFooter>
Now I'm trying to add another element. I tried to use action property:
action="<div>Some text</div>"
But that is not even showing. Tried to use
component="<td>Some text</td>"
Got the following error: Warning: validateDOMNesting(...): <<th>Some text</th>> cannot appear as a child of <tr>. Same thing with div.
Then I tried something like that:
...
<TableRow>
<TablePagination
...all the props
>
</TablePagination>
<td>Some text</td>
</TableRow>
The text appeared, but it completely scrambled my entire Table:
And <td> is about the only element that was even showing, since TableRow generates, well, <tr> element.
Any ideas how to insert an element in there?
<TableFooter>
<TableRow>
<TablePagination
...all the props
>
</TablePagination>
<TableCell colSpan={1}>
<p>Some text</p>
</TableCell>
</TableRow>
</TableFooter>
hope this can help you
You need to place the TablePagination outside of table all together.Look at the 3 example on the demos https://material-ui.com/components/tables/
<div>
<Table>
...
</Table>
</div>
<TablePagination
...props
>

Resources