i'm trying to use a table from MaterialUI and populate it with financial data (using promise API). I have three components:
Gl.js
myTable
index.js
I want to use the state object in the Gl.js component and populate the table in myTable.js but not sure how to. Please ask for more details if necessary, I must complete this project.
GL.js
import React, { Component, createContext, Provider } from 'react';
import ReactDOM from 'react-dom';
import axios from "axios";
import CollapsibleTable from './myTable';
export const CTX = React.createContext();
class Gl extends React.Component {
_isMounted = false;
constructor(props) {
super(props)
this.state = {
applBs: []
}
}
getData() {
const axios = require("axios");
axios({
"method": "GET",
"url": "https://fmpcloud.p.rapidapi.com/balance-sheet-statement/AAPL",
"headers": {
"content-type": "application/octet-stream",
"x-rapidapi-host": "fmpcloud.p.rapidapi.com",
"x-rapidapi-key": "4560d76562msh36c4de0a03c6e54p1bf4a2jsne2d882693304",
"useQueryString": true
}, "params": {
"period": "annual",
"apikey": "demo"
}
})
.then(response => {
if (this._isMounted) {
this.setState({ applBs: response.data[0] })
}
})
.catch(error => {
console.log(error)
})
}
componentDidMount() {
this._isMounted = true;
this.getData();
}
componentWillUnamount() {
this._isMounted = false;
}
render() {
return (
<div>
<CollapsibleTable callData={this.state.applBs} />
<CTX.Provider value={ this.state.applBs }>
{this.props.children}
</CTX.Provider>
</div>
)
}
}
ReactDOM.render(<Gl />, document.getElementById("root"))
export default Gl
myTable.js
import React, { Component, Consumer } from 'react';
import ReactDOM from "react-dom"
import PropTypes from 'prop-types';
import { makeStyles } from '#material-ui/core/styles';
import Box from '#material-ui/core/Box';
import Collapse from '#material-ui/core/Collapse';
import IconButton from '#material-ui/core/IconButton';
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 Typography from '#material-ui/core/Typography';
import Paper from '#material-ui/core/Paper';
import KeyboardArrowDownIcon from '#material-ui/icons/KeyboardArrowDown';
import KeyboardArrowUpIcon from '#material-ui/icons/KeyboardArrowUp';
import CTX from "./GL.js"
const useRowStyles = makeStyles({
root: {
'& > *': {
borderBottom: 'unset',
},
},
});
function createData(name, calories, fat, carbs, protein, price) {
return {
name,
calories,
fat,
carbs,
protein,
price,
history: [
{ lineItem: 'Pop', date: '2020-01-05', customerId: '11091700', amount: 3 },
{ lineItem: 'Pop', date: '2020-01-02', customerId: 'Anonymous', amount: 1 },
],
};
}
function Row(props) {
const { row } = props;
const [open, setOpen] = React.useState(false);
const classes = useRowStyles();
return (
<React.Fragment>
<TableRow className={classes.root}>
<TableCell>
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</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>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box margin={1}>
<Typography variant="h6" gutterBottom component="div">
History
</Typography>
<Table size="small" aria-label="purchases">
<TableHead>
<TableRow>
<TableCell>
Line Item
</TableCell>
<TableCell>
Google
</TableCell>
<TableCell>
Customer
</TableCell>
<TableCell align="right">
Amount
</TableCell>
<TableCell align="right">
Total price ($)
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{row.history.map((historyRow) => (
<TableRow key={historyRow.date}>
<TableCell component="th" scope="row">
{historyRow.date}
</TableCell>
<TableCell>{historyRow.customerId}</TableCell>
<TableCell align="right">{historyRow.amount}</TableCell>
<TableCell align="right">
{Math.round(historyRow.amount * row.price * 100) / 100}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
}
Row.propTypes = {
row: PropTypes.shape({
calories: PropTypes.number.isRequired,
carbs: PropTypes.number.isRequired,
fat: PropTypes.number.isRequired,
history: PropTypes.arrayOf(
PropTypes.shape({
amount: PropTypes.number.isRequired,
customerId: PropTypes.string.isRequired,
date: PropTypes.string.isRequired,
}),
).isRequired,
name: PropTypes.string.isRequired,
price: PropTypes.number.isRequired,
protein: PropTypes.number.isRequired,
}).isRequired,
};
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0, 3.99),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3, 4.99),
createData('Eclair', 262, 16.0, 24, 6.0, 3.79),
createData('Cupcake', 305, 3.7, 67, 4.3, 2.5),
createData('Gingerbread', 356, 16.0, 49, 3.9, 1.5),
];
export default function CollapsibleTable() {
return (
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<TableHead>
<TableRow>
<TableCell />
<TableCell>
Apple.Inc
</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) => (
<Row key={row.name} row={row} />
))}
</TableBody>
</Table>
</TableContainer>
);
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Gl from './GL';
import CollapsibleTable from './myTable';
ReactDOM.render(
<React.StrictMode>
<Gl >
<CollapsibleTable />
</Gl>
</React.StrictMode>,
document.getElementById('root'));
ok then this must be the issue be clear with class and functional component this keyword can be used only in class component!!
check this link for further reference link
in your case have a console in
<TableContainer component={Paper}>
{console.log('callData', props.callData)}
<Table aria-label="collapsible table">
you will get the value of callData use that to display in table
Related
Code runs and I get the table but I'm also retreiving some database data. I threw a couple console.logs in the there and my query runs and returns data. However, it doesn't show up in the collapsible table. Appreciate any advice!
import React, { useContext, useState } from "react";
import PropTypes from 'prop-types';
import { useQuery, useMutation } from "#apollo/react-hooks";
import { makeStyles } from '#material-ui/core/styles';
import Box from '#material-ui/core/Box';
import Collapse from '#material-ui/core/Collapse';
import IconButton from '#material-ui/core/IconButton';
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 Typography from '#material-ui/core/Typography';
import Paper from '#material-ui/core/Paper';
import KeyboardArrowDownIcon from '#material-ui/icons/KeyboardArrowDown';
import KeyboardArrowUpIcon from '#material-ui/icons/KeyboardArrowUp';
import CreateTicket from "views/Dashboard/CreateTicket";
import {
LIST_CREATIVE_FORM,
SUBMIT_CREATIVE_FORM,
COMPLETE_CREATIVE_FORM
} from "queries/formSubmission";
import { READ_ME } from "queries/users";
import { Context } from "redux/store";
export default function Tickets() {
const [state, dispatch] = useContext(Context);
const [selectedCreative, setSelectedCreative] = useState(null);
const customer_id = state.customers?.selected?.id;
const { data: me } = useQuery(READ_ME);
let { loading, data, refetch } = useQuery(LIST_CREATIVE_FORM, {
skip: !customer_id,
variables: { customerId: customer_id }
});
const [completeCreativeForm, { loading: completing }] = useMutation(COMPLETE_CREATIVE_FORM, {
skip: !customer_id,
onCompleted: () => {
refetch();
}
});
data = data?.listCreativeForm || [];
console.log(data);
const editable = me?.readMe?.user_level === "master" || me?.readMe?.user_level === "master";
const columns = [
{
Header: "Creative or Promotion Name",
accessor: "creative_promotion_name"
},
{
Header: "Creative Messaging",
accessor: "creative_message"
},
{
Header: "Start Date",
accessor: "creative_start"
},
{
Header: "End Date",
accessor: "creative_end"
},
{
Header: "Landing Page",
accessor: "landing_page"
},
{
Header: "Notes",
accessor: "notes"
},
{
Header: "BanerAds",
accessor: "bannerads",
Cell: ({ original }) => original?.bannerads ? "Yes" : "No"
},
{
Header: "SocialAds",
accessor: "socialads",
Cell: ({ original }) => original?.socialads ? "Yes" : "No"
},
{
Header: "OnlineVideo",
accessor: "onlinevideo",
Cell: ({ original }) => original?.onlinevideo ? "Yes" : "No"
},
{
Header: "Out of Home",
accessor: "out_of_home",
Cell: ({ original }) => original?.out_of_home ? "Yes" : "No"
},
{
Header: "Link to Asset",
accessor: "link_to_assets",
Cell: ({ original }) => (
<a href={original?.link_to_assets} target="_blank">
{original?.link_to_assets ? "View" : ""}
</a>
)
},
{
Header: "Submitted By",
accessor: "submitted_by",
Cell: ({ original }) => (
<div>{original?.user_submitted ? `${original.user_submitted?.first_name} ${original.user_submitted?.last_name}` : ""}</div>
)
},
{
Header: "Completed",
accessor: "completed",
Cell: ({ original }) => original?.completed
? <div style={{ color: "green" }}>Yes</div>
: <div style={{ color: "red" }}>No</div>
},
{
Header: "Completed By",
accessor: "completed_by",
Cell: ({ original }) => (
<>
<div>{original?.user_completed ? `${original.user_completed?.first_name} ${original.user_completed?.last_name}` : ""}</div>
{editable && !original?.completed && (
<a
href="#"
onClick={(e) => {
e.preventDefault();
completeCreativeForm({
variables: {
id: original?.id
}
});
}}
>
Complete
</a>
)}
</>
)
},
{
Header: "",
accessor: "update",
Cell: ({ original }) => (
editable && !original?.completed && (
<a
href="#"
onClick={(e) => {
e.preventDefault();
setSelectedCreative(original);
}}
>
Update
</a>
)
)
}
];
Tickets.propTypes = {
offline: PropTypes.bool
};
const useRowStyles = makeStyles({
root: {
'& > *': {
borderBottom: 'unset',
},
},
});
function Row(props) {
const { row } = props;
const [open, setOpen] = React.useState(false);
const classes = useRowStyles();
console.log("data");
console.log(data);
return (
<React.Fragment>
<TableRow className={classes.root} columns={columns} data={data}>
<TableCell>
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
<TableCell align="right">{data.values.creative_promotion_name} lhey</TableCell>
<TableCell align="right">{data.values.creative_message}</TableCell>
<TableCell align="right">{data.values.creative_start}</TableCell>
<TableCell align="right">{data.values.creative_end}</TableCell>
</TableRow>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box margin={1}>
<Typography variant="h6" gutterBottom component="div">
History
</Typography>
<Table size="small" aria-label="purchases">
<TableHead>
<TableRow>
<TableCell>Date</TableCell>
<TableCell>Customer</TableCell>
<TableCell align="right">Amount</TableCell>
<TableCell align="right">Total price ($)</TableCell>
</TableRow>
</TableHead>
{/*<TableBody>
{row.history.map((historyRow) => (
<TableRow key={historyRow.date}>
<TableCell component="th" scope="row">
{historyRow.date}
</TableCell>
<TableCell>{historyRow.customerId}</TableCell>
<TableCell align="right">{historyRow.amount}</TableCell>
<TableCell align="right">
{Math.round(historyRow.amount * row.price * 100) / 100}
</TableCell>
</TableRow>
))}
</TableBody>*/}
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
}
console.log(columns)
return (
<TableContainer component={Paper}>
<Table aria-label="collapsible table" columns={columns} data={data}>
<TableBody>
{data.map((row) => (
<Row key={row.id} row={row} />
))}
</TableBody>
</Table>
</TableContainer>
);
}
Ok so here's what code worked for me to pass my database data to the collapsible table...
function Row(props) {
const { row } = props;
const [open, setOpen] = React.useState(false);
const classes = useRowStyles();
return (
<React.Fragment>
<TableRow>
<TableCell>
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
<TableCell align="right">{row.creative_promotion_name}</TableCell>
<TableCell align="right">{row.creative_message}</TableCell>
<TableCell align="right">{row.creative_start}</TableCell>
<TableCell align="right">{row.creative_end}</TableCell>
<TableCell align="right">{row.out_of_home}</TableCell>
<TableCell align="right">{row.link_to_assets}</TableCell>
<TableCell align="right">{row.submitted_by}</TableCell>
<TableCell align="right">{row.completed}</TableCell>
<TableCell align="right">{row.completed_by}</TableCell>
<TableCell align="right">{row.update}</TableCell>
</TableRow>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={4}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box margin={1}>
<Table size="small" aria-label="purchases">
<TableRow>
<TableCell>Notes:</TableCell>
<TableCell align="left">{row.notes}</TableCell>
</TableRow>
<TableRow>
<TableCell>Created Time:</TableCell>
<TableCell align="left">{row.created_time}
</TableCell>
</TableRow>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
}
const classes = useRowStyles();
return (
<div>
<TableContainer component={Paper} style={{overflowY: "auto", maxWidth: "100%", maxHeight: "600px"}}>
<h2 className={classes.pageHeader}>Tickets</h2>
<Table stickyHeader aria-label="collapsible table" columns={columns} data={data}>
<TableHead>
<TableRow>
<TableCell />
{columns.map((data) => (
<TableCell>{data.Header}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{data.map((datarow) => (
<Row data={datarow.id} row={datarow} />
))}
</TableBody>
</Table>
</TableContainer>
</div>
);
}
The thing is i have dynamic tables which is coming from an API and on clicking the down arrow icon those specific data are getting fetched depending on the Table Names and are displayed as a table data but the problem is when user clicks on one row and after that if the user clicks on another row at the same time one Table data has to be shown or one row needs to get expanded at a time
like if i click the second row other rows will be closed only the second row table data will be visible
Row Component
import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '#material-ui/core/styles';
import Box from '#material-ui/core/Box';
import Collapse from '#material-ui/core/Collapse';
import IconButton from '#material-ui/core/IconButton';
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 Typography from '#material-ui/core/Typography';
import Paper from '#material-ui/core/Paper';
import KeyboardArrowDownIcon from '#material-ui/icons/KeyboardArrowDown';
import KeyboardArrowUpIcon from '#material-ui/icons/KeyboardArrowUp';
const useRowStyles = makeStyles({
root: {
'& > *': {
borderBottom: 'unset',
},
},
});
function createData(name, calories, fat, carbs, protein, price) {
return {
name,
calories,
fat,
carbs,
protein,
price,
history: [
{ date: '2020-01-05', customerId: '11091700', amount: 3 },
{ date: '2020-01-02', customerId: 'Anonymous', amount: 1 },
],
};
}
function Row(props) {
const { row } = props;
const [open, setOpen] = React.useState(false);
const classes = useRowStyles();
return (
<React.Fragment>
<TableRow className={classes.root}>
<TableCell>
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</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>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box margin={1}>
<Typography variant="h6" gutterBottom component="div">
History
</Typography>
<Table size="small" aria-label="purchases">
<TableHead>
<TableRow>
<TableCell>Date</TableCell>
<TableCell>Customer</TableCell>
<TableCell align="right">Amount</TableCell>
<TableCell align="right">Total price ($)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{row.history.map((historyRow) => (
<TableRow key={historyRow.date}>
<TableCell component="th" scope="row">
{historyRow.date}
</TableCell>
<TableCell>{historyRow.customerId}</TableCell>
<TableCell align="right">{historyRow.amount}</TableCell>
<TableCell align="right">
{Math.round(historyRow.amount * row.price * 100) / 100}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
}
Row.propTypes = {
row: PropTypes.shape({
calories: PropTypes.number.isRequired,
carbs: PropTypes.number.isRequired,
fat: PropTypes.number.isRequired,
history: PropTypes.arrayOf(
PropTypes.shape({
amount: PropTypes.number.isRequired,
customerId: PropTypes.string.isRequired,
date: PropTypes.string.isRequired,
}),
).isRequired,
name: PropTypes.string.isRequired,
price: PropTypes.number.isRequired,
protein: PropTypes.number.isRequired,
}).isRequired,
};
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0, 3.99),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3, 4.99),
createData('Eclair', 262, 16.0, 24, 6.0, 3.79),
createData('Cupcake', 305, 3.7, 67, 4.3, 2.5),
createData('Gingerbread', 356, 16.0, 49, 3.9, 1.5),
];
CollapsibleTable Component
export default function CollapsibleTable() {
return (
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<TableBody>
{rows.map((row) => (
<Row key={row.name} row={row} />
))}
</TableBody>
</Table>
</TableContainer>
);
}
dsdsd
you could add an open and onClick property to row that is populated by your table. example:
function Row(props: any) {
const { row } = props;
const classes = useRowStyles();
return (
<React.Fragment>
<TableRow className={classes.root}>
<TableCell>
<IconButton aria-label="expand row" size="small" onClick={() => props.onClick(props.open ? "" : row.name)}>
{props.open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</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>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
<Collapse in={props.open} timeout="auto" unmountOnExit>
<Box margin={1}>
<Typography variant="h6" gutterBottom component="div">
History
</Typography>
<Table size="small" aria-label="purchases">
<TableHead>
<TableRow>
<TableCell>Date</TableCell>
<TableCell>Customer</TableCell>
<TableCell align="right">Amount</TableCell>
<TableCell align="right">Total price ($)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{row.history.map((historyRow: any) => (
<TableRow key={historyRow.date}>
<TableCell component="th" scope="row">
{historyRow.date}
</TableCell>
<TableCell>{historyRow.customerId}</TableCell>
<TableCell align="right">{historyRow.amount}</TableCell>
<TableCell align="right">
{Math.round(historyRow.amount * row.price * 100) / 100}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
}
your table looks like this:
export default function CollapsibleTable() {
const [openRow, setOpenRow] = useState("")
return (
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<TableBody>
{rows.map((row) => (
<Row key={row.name} row={row} open={row.name == openRow} onClick={(name) => setOpenRow(name)} />
))}
</TableBody>
</Table>
</TableContainer>
);
}
I'm using Material UI table example and trying to customize the rows to have my own component to replace the default row.I want to have some margin between the rows and a shadow (using elevation prop of Paper element). This is what I achieved so far:
import React, { useState } from 'react'
import Paper from '#material-ui/core/Paper';
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';
const MyPaper = (item) => {
return (
<Paper
elevation={6}>
{item}
</Paper>
);
};
const List = () => {
const items = ['a', 'b'];
return (
<div style={{ maxWidth: "100%" }}>
<TableContainer>
<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>
{items.map(item => (
<TableRow key={item} component={() => MyPaper(item)}>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</div>
)
}
export default List
but the result is being applied only in the first column. How do I fix this to have my custom row to occupy the entire table space?
Thanks in advance
You can do it easily with withstyles property of Material-UI, you can arrange Paper or other MUI components to give them classes and arrange them in styles variable:
import React, { useState } from 'react'
import Paper from '#material-ui/core/Paper';
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 { WithStyles } from '#material-ui/core'
const styles = theme => ({
...theme,
Row: {
margin: 10
}
})
const List = () => {
const items = ['a', 'b'];
const {classes} = this.props
return (
<div style={{ maxWidth: "100%" }}>
<TableContainer>
<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>
{items.map(item => (
<TableRow key={item} className={classes.Row}>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
<TableCell>{item}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</div>
)
}
export default withStyles(styles)(List)
I'd be grateful if you could help me with my problem.
I've written a component to demonstrate the information of an array which includes both index.js and TableData.js files.Transferring the information of array from index.js to TableData in order to demonstrating them.
I passed the arguments to event handler correctly but I get an error. What's the problem with my code? In which part have I made a mistake?
App.js
import React, {Component, Fragment} from 'react';
import {TableData} from './Layouts'
class App extends Component {
state = {
productList: [
{id: 11, name: 'CD', price: '2000', describe: 'Educational'},
{id: 24, name: 'Pen', price: '3500', describe: 'Design'},
{id: 83, name: 'Pencil', price: '2500', describe: 'Design'}
],
};
handleDeleteByIndex = index => {
const product = this.state.productList;
product.splice(index, 1);
this.setState({productList: product});
};
render() {
const {productList} = this.state;
return (
<Fragment>
<TableData rows={productList} onDeleteRow={this.handleDeleteByIndex}/>
</Fragment>
);
}
}
export default App
TableData.js
import React from 'react';
import {makeStyles} from '#material-ui/core/styles';
import {
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Paper
} from '#material-ui/core';
//****** Style CSS ******
const useStyles = makeStyles({
root: {
width: '100%',
overflowX: 'auto'
},
table: {
minWidth: 650
}
});
const test = 'right';
const TableData= (props) => {
const classes = useStyles();
return (
<Paper className={classes.root}>
<Table className={classes.table} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Name Product</TableCell>
<TableCell align="right">Price</TableCell>
<TableCell align="right">Describe</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.rows.map((item, index) => (
<TableRow key={item.id}>
<TableCell component="th" scope="row">
{item.name}
</TableCell>
<TableCell align={test} data={item.name}>{item.price}</TableCell>
<TableCell align="right">{item.describe}</TableCell>
<TableCell align="right">
<button onClick={() => props.handleDeleteByIndex(index)}>
DEL
</button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
);
};
export default TableData
You are calling a function that does not exist. The passed down function in props is called onDeleteRow, not handleDeleteByIndex.
Just change it into:
onClick={() => props.onDeleteRow(index)}
I am using the Table control from material UI to display the data , but right now I have the requirement to show the group data,with expand and collapsed data.Is there any package present to achieve this goal?Please assist me.
import { TableRowProps, Table, TableBody, TableFooter, PagiFooter, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
<Table>
<TableHeader {...headerProps}>
{this.renderHeaders()}
</TableHeader>
<TableBody displayRowCheckbox={false}
deselectOnClickaway={false}>
{this.renderRows()}
</TableBody>
</Table>
The Table component doesn't currently support expansion, but you can hack around that using the expandable card component, just make sure you adjust the vertical alignment of the row.
Here's a code snippet:
<TableBody displayRowCheckbox={false}>
{this.props.user.leads.map((lead, i) => (
<TableRow key={i}>
<TableRowColumn>
<Card style={{boxShadow: 'none'}}>
<CardHeader
title={lead.brand}
style={{paddingLeft: 0, fontWeight: 600}}
actAsExpander={true}
/>
<CardText expandable={true}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Donec mattis pretium massa. Aliquam erat volutpat. Nulla facilisi.
Donec vulputate interdum sollicitudin. Nunc lacinia auctor quam sed pellentesque.
Aliquam dui mauris, mattis quis lacus id, pellentesque lobortis odio.
</CardText>
</Card>
</TableRowColumn>
<TableRowColumn style={{verticalAlign: 'top', height: 'auto', paddingTop: '1.4em'}}>{lead.budget}</TableRowColumn>
<TableRowColumn style={{verticalAlign: 'top', height: 'auto', paddingTop: '1.4em'}}>{lead.eventName ? 'Event' : 'Content'}</TableRowColumn>
<TableRowColumn style={{verticalAlign: 'top', height: 'auto', paddingTop: '1.4em'}}>{lead.firstName + ' ' + lead.lastName}</TableRowColumn>
<TableRowColumn style={{verticalAlign: 'top', height: 'auto', paddingTop: '1.4em'}}>Archive | Start Campaign</TableRowColumn>
</TableRow>
))}
</TableBody>
An approach for Material Ui , but can be used with same structure in other table formats:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } 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 Collapse from '#material-ui/core/Collapse';
import CardActions from '#material-ui/core/CardActions';
import IconButton from '#material-ui/core/IconButton';
import ExpandMoreIcon from '#material-ui/icons/ExpandMore';
const styles = theme => ({
root: {
width: '100%',
marginTop: theme.spacing.unit * 3,
overflowX: 'auto',
},
table: {
minWidth: 700,
},
expand: {
transform: 'rotate(0deg)',
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest,
}),
marginLeft: 'auto',
[theme.breakpoints.up('sm')]: {
marginRight: -8,
},
},
expandOpen: {
transform: 'rotate(180deg)',
},
});
let id = 0;
function createData(name, calories, fat, carbs, protein) {
id += 1;
return { id, name, calories, fat, carbs, protein };
}
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
createData('Gingerbread', 356, 16.0, 49, 3.9)
];
class TableGroup extends React.Component {
constructor(props) {
super(props);
this.state = { expanded: {} };
}
handleExpandClick(key) {
let state = { ...this.state };
state.expanded[key] = !!!state.expanded[key];
this.setState(state);
}
render() {
const props = this.props;
const { groupProperty, rows, ...other } = props;
const groups = rows.reduce((acc, row) => {
acc[row[groupProperty]] = acc[row[groupProperty]] || [];
acc[row[groupProperty]].push(row);
return acc;
}, {});
const keys = Object.keys(groups);
return keys.map(key => (
<TableRow>
<TableCell colspan="5">
<CardActions disableActionSpacing>
<b>{key} ({groups[key].length})</b>
<IconButton
className={this.state.expanded[key] ? props.classes.expandOpen : props.classes.expand}
onClick={this.handleExpandClick.bind(this, key)}
aria-expanded={this.state.expanded[key]}
aria-label="Show more"
>
<ExpandMoreIcon />
</IconButton>
</CardActions>
<Collapse in={this.state.expanded[key]} timeout="auto" unmountOnExit>
<Table {...other}>
<TableBody>
{groups[key].map(row => (
<TableRow key={row.id}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell numeric>{row.calories}</TableCell>
<TableCell numeric>{row.fat}</TableCell>
<TableCell numeric>{row.carbs}</TableCell>
<TableCell numeric>{row.protein}</TableCell>
</TableRow>
)
)}
</TableBody>
</Table>
</Collapse>
</TableCell>
</TableRow>
)
)
}
};
function SimpleTable(props) {
const { classes } = props;
return (
<Paper className={classes.root}>
<Table >
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell numeric>Calories</TableCell>
<TableCell numeric>Fat (g)</TableCell>
<TableCell numeric>Carbs (g)</TableCell>
<TableCell numeric>Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableGroup classes={classes} rows={rows} groupProperty="name" />
</TableBody>
</Table>
</Paper>
);
}
SimpleTable.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SimpleTable);
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 DataCard = ({ show }) => {
const classes = useStyles();
const [open, setOpen] = useState();
const handleExpandedClick = index => (e) => {
setOpen(index === open ? '' : index);
}
return (
<Only when={show}>
<Paper className={classes.root}>
<Table className={classes.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, index) => (
<>
<TableRow
key={index}
hover
style={{ cursor: 'pointer' }}
onClick={handleExpandedClick(index)}
>
<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>
<Collapse in={open === index} hidden={open !== index} component="tr" style={{ display: "block" }}>
<td>
<div>Expanded data.</div>
</td>
</Collapse>
</>
))}
</TableBody>
</Table>
</Paper>
</Only>
)
}
DataCard.propTypes = {
show: PropTypes.bool.isRequired
}
export default DataCard;
Thank you #bluehipy, I have managed rewrite the code with hooks
import React, { useEffect, useState } from "react";
import PropTypes from "prop-types";
import { withStyles } 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 Collapse from "#material-ui/core/Collapse";
import CardActions from "#material-ui/core/CardActions";
import IconButton from "#material-ui/core/IconButton";
import ExpandMoreIcon from "#material-ui/icons/ExpandMore";
import getOrdersBasedOnRouteQuery from "../graphql/queries/getOrdersBasedOnRouteQuery";
const styles = theme => ({
root: {
width: "100%",
marginTop: theme.spacing.unit * 3,
overflowX: "auto"
},
table: {
minWidth: 700
},
expand: {
transform: "rotate(0deg)",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest
}),
marginLeft: "auto",
[theme.breakpoints.up("sm")]: {
marginRight: -8
}
},
expandOpen: {
transform: "rotate(180deg)"
}
});
const grouped = values => {
let finalArray = [];
values.customers.filter(orders => {
return Array.prototype.push.apply(finalArray, orders);
});
return finalArray;
};
const TableGroup = ({ classes, routes, ...other }) => {
const [expanded, setExpanded] = useState({});
const handleExpandClick = value => {
setExpanded(expanded => {
return {
...expanded,
[value]: expanded[value] ? false : true
};
});
};
return routes.map((route, routeIndex) => {
return (
<TableRow>
<TableCell colspan="5">
<CardActions disableActionSpacing>
<b>
{route.name} - ({grouped(route).length}){" "}
</b>
<IconButton
className={
expanded[route.name] ? classes.expandOpen : classes.expand
}
onClick={() => handleExpandClick(route.name)}
aria-expanded={route.name}
aria-label="Show more"
>
<ExpandMoreIcon />
</IconButton>
</CardActions>
<Collapse in={expanded[route.name]} timeout="auto" unmountOnExit>
<Table {...other}>
<TableBody>
{grouped(route).map(row => {
return (
<TableRow key={row.id}>
<TableCell text>{row.reference}</TableCell>
<TableCell text>{row.customer.full_name}</TableCell>
<TableCell numeric>{row.total}</TableCell>
<TableCell>{row.status}</TableCell>
<TableCell>{row.created_at}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</Collapse>
</TableCell>
</TableRow>
);
});
};
const SimpleTable = ({ classes }) => {
const [routes, setRoutes] = useState([]);
const [loading, setLoading] = useState(true);
const fetchAllOrders = async () => {
const result = await getOrdersBasedOnRouteQuery();
if (!result.loading) {
setRoutes(result.data.route);
setLoading(false);
}
};
useEffect(() => {
fetchAllOrders();
}, [loading === true]);
if (loading) {
return <div>Loading...</div>;
}
return (
<Paper className={classes.root}>
<Table>
<TableHead>
<TableRow>
<TableCell>Reference</TableCell>
<TableCell numeric>Customer Name</TableCell>
<TableCell numeric>Total</TableCell>
<TableCell numeric>Status</TableCell>
<TableCell numeric>Created At</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableGroup classes={classes} routes={routes} groupProperty="name" />
</TableBody>
</Table>
</Paper>
);
};
SimpleTable.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(SimpleTable);