I'm trying to collapse a datatable in material-ui and show only the table header with total number of rows in the datatable. Is there a datatable plugin that allows me to do this?
Show the number of rows by taking the length of your array... relevant js:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Table from '#material-ui/core/Table';
import TableBody from '#material-ui/core/TableBody';
import TableCell from '#material-ui/core/TableCell';
import TableHead from '#material-ui/core/TableHead';
import TableRow from '#material-ui/core/TableRow';
import Paper from '#material-ui/core/Paper';
import Badge from '#material-ui/core/Badge';
const useStyles = makeStyles({
root: {
width: '100%',
overflowX: 'auto',
},
table: {
minWidth: 650,
},
});
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
];
export default function SimpleTable() {
const classes = useStyles();
return (
<Paper className={classes.root}>
<Table className={classes.table} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>
<Badge className={classes.margin} badgeContent={rows.length} color="primary">
</Badge>
</TableCell> <TableCell>Dessert (100g serving)
</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow key={row.name}>
<TableCell align="right"></TableCell>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
);
}
hide the tbody using display:none on the class of the tbody... relevant css:
.MuiTableBody-root{
display: none;
}
complete working stackblitz here
Related
I encountered the case having a Link in a specific row and onClick function which triggers if any of rows is clicked. So for the row, that has a Link I don't want to trigger onClick function, but can't find out the correct approach.
Any help will be appreciated.
Codesandobox link
And Code example below
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";
import { Link } from "#mui/material";
function createData(
name: string,
calories: number,
fat: number,
carbs: number,
protein: number
) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
createData("Eclair", 262, 16.0, 24, 6.0),
createData("Cupcake", 305, 3.7, 67, 4.3),
createData("Gingerbread", 356, 16.0, 49, 3.9)
];
export default function BasicTable() {
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow onClick={() => alert("test")} key={row.name}>
<Link
target="_blank"
rel="noopener noreferrer"
underline="hover"
href="https://www.google.com/"
sx={{ cursor: "pointer" }}
color="inherit"
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
</Link>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
you can add:
onClick={(e) => e.stopPropagation()}
to your Link element. This way, when the Link is clicked, the click event won't propagate to the parent TableRow
This might help
<TableBody>
{rows.map((row,i) => (
<TableRow onClick={() => {if(!document.getElementById(`row${i}`)) alert("test")}} key={row.name}>
<Link
id={`row${i}`}
target="_blank"
rel="noopener noreferrer"
underline="hover"
href="https://www.google.com/"
sx={{ cursor: "pointer" }}
color="inherit"
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
</Link>
I'm using the DenseTable component of the ui material and I want to be able to get all the data from the clicked row, if anyone knows it would be a big help
Below is the source code of the component I'm using:
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';
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
];
export default function DenseTable() {
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} size="small" aria-label="a dense table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
key={row.name}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
i know the ui material has several components with this action but they are very elaborate and i want a simple table
You can add onClick handler in the TableRow and when clicked on the row, store the row data in the state variable or whatever the UX is
const [selectedRow, setSelectedRow] = React.useState({});
<TableRow
onClick={() => setSelectedRow(row)}
key={row.name}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
Complete code will be something like below
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";
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
createData("Eclair", 262, 16.0, 24, 6.0),
createData("Cupcake", 305, 3.7, 67, 4.3),
createData("Gingerbread", 356, 16.0, 49, 3.9)
];
export default function DenseTable() {
const [selectedRow, setSelectedRow] = React.useState({});
console.log({ selectedRow });
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} size="small" aria-label="a dense table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
onClick={() => setSelectedRow(row)}
key={row.name}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
I am working with React and Material UI and I am trying to give a broder-radius of 10px to the header of the table so that only the TableHead have round corners.
The problem is that border-radius doesn't seem to work at all on TableHead as you can see in this screenshot:
Code (taken from the official docs, I just added the style to the TableHead):
<TableContainer>
<Table aria-label="customized table">
<TableHead style={{ backgroundColor: '#E2E2E2', borderRadius: '10px' }}>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>;
How do I get this done?
As far as I know, there are no ways to set border-radius for the entire tablerow, but the problem can be solved by using a separate radius for the first and last cells:
const { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, makeStyles } = MaterialUI
const useStyles = makeStyles((theme) => ({
table: {
minWidth: 400,
},
thead: {
backgroundColor: 'lightgray',
'& th:first-child': {
borderRadius: '1em 0 0 1em'
},
'& th:last-child': {
borderRadius: '0 1em 1em 0'
}
}
}))
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein }
}
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
]
const App = function () {
const classes = useStyles()
return (
<TableContainer component={Paper}>
<Table className={classes.table} aria-label="customized table">
<TableHead classes={{ root: classes.thead }}>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">{row.name}</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)}
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://unpkg.com/react#17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#17.0.2/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/#material-ui/core#4.11.3/umd/material-ui.development.js"></script>
<div id="root"></div>
You can continue using the makeStyles hook generator to style the table header.
import { makeStyles } from '#material-ui/core/styles';
const useTableHeaderStyles = makeStyles({
// .MuiTableHead-root
root: {
backgroundColor: '#E2E2E2',
borderRadius: '10px',
},
});
In the component:
const tableHeaderClasses = useTableHeaderStyles();
...
<TableHead classes={tableHeaderClasses.root}>
...
</TableHead>
I have the following code. Its same as the basic table from material ui. Only thing i have modified the First row, second column content. I am using a Grid element inside it. and also added more columns so that i can see a horizontal scroll scenario
I dont want it to break.
import React from 'react';
import Table from '#material-ui/core/Table';
import TableBody from '#material-ui/core/TableBody';
import TableCell from '#material-ui/core/TableCell';
import TableContainer from '#material-ui/core/TableContainer';
import TableHead from '#material-ui/core/TableHead';
import TableRow from '#material-ui/core/TableRow';
import Paper from '#material-ui/core/Paper';
import Grid from '#material-ui/core/Grid';
import { createMuiTheme, makeStyles, ThemeProvider } from '#material-ui/core/styles';
const hare = makeStyles({
table: {
minWidth: 650,
},
});
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData('Frozen yoghurt',
159,
<Grid container alignItems="center" justify="space-between" spacing={10}>
<Grid item>
Dont
</Grid>
<Grid item>
Break
</Grid>
</Grid>,
24,
4.0
),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
];
export default function BasicTable() {
const classes = hare();
return (
<TableContainer component={Paper}>
<Table className={classes.table} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
What is see is
You can use the wrap="nowrap" prop on the Grid. From the docs:
wrap - Defines the flex-wrap style property. It's applied for all screen sizes.
Just the excerpt that I've changed, and the codesandbox
<Grid container wrap="nowrap" alignItems="center" justify="space-between" spacing={10}>
<Grid item>Dont</Grid>
<Grid item>Break</Grid>
</Grid>
I'm trying to create space between each rows of table component. I used classname and classes props on TableRow, TableCell, TableBody and Table, but nothing worked. I also tried to create custom theme but it also not working. Here's the code,
const useStyles = makeStyles({
table: {
minWidth: 650
},
tableRow: {
cursor: "pointer",
borderLeft: "8px solid #9a031e",
marginTop: "8px"
},
tableCell: {
marginTop: "8px"
}
});
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
createData("Eclair", 262, 16.0, 24, 6.0),
createData("Cupcake", 305, 3.7, 67, 4.3),
createData("Gingerbread", 356, 16.0, 49, 3.9)
];
export default function BasicTable() {
const classes = useStyles();
return (
<TableContainer component={Paper}>
<Table className={classes.table} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody component={Paper}>
{rows.map((row) => (
<TableRow
key={row.name}
className={classes.tableRow}
styles={{ marginTop: 8 }}
>
<TableCell component="th" scope="row" style={{ width: 100 }}>
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
Please do let me what am I doing wrong? How can I achieve it?
You can use border-collapse and border-spacing just inside table style. Thats all.
table: {
minWidth: 650,
borderCollapse: 'separate',
borderSpacing: '0px 4px'
}
To know more see: Cannot put margin on <td> tag with neither CSS nor cellspacing attribute