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

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>
)

Related

How to animate Table Item Entry using TransitionGroup and Material UI Tables in ReactJS

I am having an issue where I can't seem to get TransitionGroup to work with Material UI ReactJS library
My expectation is pretty simple, upon entry into the table the row should be animated in like sliding into the table.
I have tried the following but this only end up scattering the table, the headers and everything becomes out of shape.
Here is what I have tried using the Material UI library for ReactJS
<TableContainer>
<Table aria-label="stats-table">
<TableHead>
<TableRow>
{...}
</TableRow>
</TableHead>
<TransitionGroup
transitionName="fade"
transitionEnterTimeout={1000}
transitionLeaveTimeout={300}
transitionAppearTimeout={1000}
transitionAppear={true}
component="tbody">
<TableBody>
{
(rowsPerPage > 0 ? games.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) : games
).map((row: Game) => (
<SimpleTableRow row={row} key={row.id}/>
))}
{
emptyRows > 0 && (
<TableRow style={{height: 53 * emptyRows}}>
<TableCell colSpan={6}/>
</TableRow>
)
}
</TableBody>
</TransitionGroup>
</TableContainer>
The moment I add the TransitionGroup, the entire table headers and body becomes scattered.
How can I make this work? Thanks
You can try to pass component={null} instead component="tbody".

How to highlight a specific table cell in material UI table in react based on a text search

I have implemented a Material UI table and forming up the table based on the array of objects.
For example my array of objects:
[{id:1, name:abc, age: 12},{id:2, name:def, age: 13},{id:3, name:ghi, age: 14}].
This is my code for generating the table using material-ui for react.
return (
<div className={classes.root}>
{data.name}
<Paper className={classes.paper}>
<EnhancedTableToolbar handleSearch={handleSearch} value={searchValue} />
<TableContainer className={classes.container}>
<Table
className={classes.table}
aria-labelledby="tableTitle"
stickyHeader aria-label="sticky table"
>
<EnhancedTableHead
classes={classes}
order={order}
orderBy={orderBy}
onRequestSort={handleRequestSort}
/>
<TableBody>
{displaySortedData(data, getComparator(order, orderBy))
.map((row, index) => {
return (
<TableRow
hover
tabIndex={-1}
key={row.ID}
>
<TableCell style={{ textAlign: "center", cursor: "pointer" }}>
<EditIcon />
</TableCell>
<TableCell component="th" scope="row" align="right">
{row.ID}
</TableCell>
<TableCell align="left"><span className={row.name.match(searchValue) ? classes.tableCell : "" }>{row.SOR_NAME}</span></TableCell>
<TableCell align="left">{row.age}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
</Paper>
</div>
);
Now whenever user type in search box i capture that in searchValue. Based on the searchValue i change the array of objects and display the table. Now i need to highlight the text too in the table for the searched text.
For that i compare the search value in the 4rth table cell as you can see above in the code.
But my issue is that it highlights the entire column and not just the single table cell in which it found the exact search match. I understand as i am writing the comparison in the tableCell, that is why it highlights the entire column. But i only want to highlight a specific cell of that table if it exactly matches the searched text.
The EnhancedTableHead returns the table headers.
This one works for highlighting the table cell and not the word. For example if user types "match" in search field. Then with the help of following function it highlights the table cell but doesnt highlight the actual characters of the word. For example if in a table cell the word "MatchingWord", it will highlight the full word but not just "Match" in "MatchingWord"
const highlight = (classes, rowValues) =>{
if(searchValue == null || searchValue == "" || rowValues == null || rowValues == "") {
return classes.notMatchingTableCell
} else if(rowValues.toLowerCase().includes(searchValue.toLowerCase()) == true) {
return classes.tableCell
}
return classes.notMatchingTableCell
}
Here classes i pass is the actual css class for higlighting. And rowValues is the value of the row for that object. So in the material ui table part add this function in tag like this
<TableCell align="left"><span className= {highlight(classes, row.age)}>{row.age}</span></TableCell>

conditional enclosing elements React

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>

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
>

How to hide/show columns with material-ui table?

I'm using http://www.material-ui.com, Is it possible to hide/show columns based on the device? For example, on desktop, I want to show 6 columns but on a phone, I might want to show 3 specific columns. How to do this?
I know I am late but this answer is for someone who wants to do it with only material-ui.
Material-ui provides theme breakpoints and withWidth HOC. Both of them can be used to show/hide columns on device size.
Here is an example of using theme breakpoints to change styles based on device width. Same concept can be used to hide/show columns.
You can specify a CSS className on the corresponding TableHeaderColumn and TableRowColumn elements that is hidden/shown depending on a CSS #media query.
For convenience sake, I'm using Bootstrap below and its "hidden-xs" CSS class, which provides such a media query. You'll see that the "Status" column is hidden when you resize the browser window below a certain width.
https://jsfiddle.net/2uepwbd9/1/
class Example extends React.Component {
render() {
return (
<div>
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn>ID</TableHeaderColumn>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn className="hidden-xs">Status</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableRowColumn>1</TableRowColumn>
<TableRowColumn>John Smith</TableRowColumn>
<TableRowColumn className="hidden-xs">Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>2</TableRowColumn>
<TableRowColumn>Randal White</TableRowColumn>
<TableRowColumn className="hidden-xs">Unemployed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>3</TableRowColumn>
<TableRowColumn>Stephanie Sanders</TableRowColumn>
<TableRowColumn className="hidden-xs">Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>4</TableRowColumn>
<TableRowColumn>Steve Brown</TableRowColumn>
<TableRowColumn className="hidden-xs">Employed</TableRowColumn>
</TableRow>
</TableBody>
</Table>
</div>
);
}
}
You could use a grid library like reflexbox.
There's a Hidden component that does exactly what you're asking for. See the documentation.

Resources