admin管理员组

文章数量:1289828

I would like to implement Google's Material UI Menu Item inside of a TableCell, as shown in their docs here, as seen below:

Here is my current approach:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import {
  Grid,
  IconButton,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  Paper,
  Menu,
  MenuItem,
  Button,
} from '@material-ui/core';
import { ExpandLess, ExpandMore } from '@material-ui/icons';

const styles = theme => ({});

const Questions = ({ data, classes, openMenu, anchorEls, handleClose }) => {
  const CustomTableCell = withStyles(theme => ({
    head: {
      backgroundColor: theme.palettemon.black,
      color: theme.palettemon.white,
    },
    body: {
      fontSize: 14,
    },
  }))(TableCell);

  const formatData = rawData => Object.keys(rawData).map(key => rawData[key]);

  const n = { key: 'hi', rating: 55, text: 'wassup' };

  return (
    <Grid container alignItems={'center'} direction={'column'} spacing={8}>
      <Paper className={classes.root}>
        <Button
          key="close"
          aria-label="Close"
          color="inherit"
          className={classes.close}
          onClick={e => openMenu('dude', e)}
        >
          <ExpandMore />
        </Button>
        <Menu
          id={`dude`}
          key="menu"
          anchorEl={anchorEls.dude}
          open={Boolean(anchorEls.dude)}
          onClose={e => handleClose('dude', e)}
        >
          <MenuItem onClick={e => handleClose('dude', e)}>Delete</MenuItem>
          <MenuItem onClick={e => handleClose('dude', e)}>Flag</MenuItem>
          <MenuItem onClick={e => handleClose('dude', e)}>
            Mark Answered
          </MenuItem>
        </Menu>
        <Table className={classes.table}>
          <TableHead>
            <TableRow>
              <CustomTableCell>Question</CustomTableCell>
              <CustomTableCell numeric>Rating</CustomTableCell>
              <CustomTableCell>Upvote</CustomTableCell>
              <CustomTableCell>Downvote</CustomTableCell>
              <CustomTableCell>Options</CustomTableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            <TableRow className={classes.row} key={n.key}>
              <CustomTableCell ponent="th" scope="row">
                {n.text}
              </CustomTableCell>
              <CustomTableCell numeric>{n.rating}</CustomTableCell>
              <CustomTableCell>
                <IconButton
                  key="close"
                  aria-label="Close"
                  color="inherit"
                  className={classes.close}
                  onClick={() => ''}
                >
                  <ExpandLess />
                </IconButton>
              </CustomTableCell>
              <CustomTableCell>
                <IconButton
                  key="close"
                  aria-label="Close"
                  color="inherit"
                  className={classes.close}
                  onClick={() => ''}
                >
                  <ExpandMore />
                </IconButton>
              </CustomTableCell>
              <CustomTableCell>
                <Button
                  key="close"
                  aria-label="Close"
                  color="inherit"
                  className={classes.close}
                  onClick={e => openMenu(n.key, e)}
                >
                  <ExpandMore />
                </Button>
                <Menu
                  id={`simple-menu-${n.key}`}
                  key="menu"
                  anchorEl={anchorEls[n.key]}
                  open={Boolean(anchorEls[n.key])}
                  onClose={e => handleClose(n.key, e)}
                >
                  <MenuItem onClick={e => handleClose(n.key, e)}>
                    Delete
                  </MenuItem>
                  <MenuItem onClick={e => handleClose(n.key, e)}>dude</MenuItem>
                  <MenuItem onClick={e => handleClose(n.key, e)}>choc</MenuItem>
                </Menu>
              </CustomTableCell>
            </TableRow>
          </TableBody>
        </Table>
      </Paper>
    </Grid>
  );
};

Questions.propTypes = {
  data: PropTypes.object.isRequired,
  anchorEls: PropTypes.object.isRequired,
  classes: PropTypes.object.isRequired,
  openMenu: PropTypes.func.isRequired,
  handleClose: PropTypes.func.isRequired,
};

Questions.defaultProps = {};

export default withStyles(styles)(Questions);

This is working, however the menu is not appearing in the correct place, even when passing in the related event e. I put in a dummy element before the table to test whether or not the table was affecting the menu, and found that the dummy worked just fine, as you can see in the screenshot below.

And the improperly placed menu from the button in the table:

Any ideas on what could be happening? Obviously, the context and anchorEl isn't correctly identifying the location on the page, but not sure what to do to bat that.

I would like to implement Google's Material UI Menu Item inside of a TableCell, as shown in their docs here, as seen below:

Here is my current approach:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import {
  Grid,
  IconButton,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  Paper,
  Menu,
  MenuItem,
  Button,
} from '@material-ui/core';
import { ExpandLess, ExpandMore } from '@material-ui/icons';

const styles = theme => ({});

const Questions = ({ data, classes, openMenu, anchorEls, handleClose }) => {
  const CustomTableCell = withStyles(theme => ({
    head: {
      backgroundColor: theme.palette.mon.black,
      color: theme.palette.mon.white,
    },
    body: {
      fontSize: 14,
    },
  }))(TableCell);

  const formatData = rawData => Object.keys(rawData).map(key => rawData[key]);

  const n = { key: 'hi', rating: 55, text: 'wassup' };

  return (
    <Grid container alignItems={'center'} direction={'column'} spacing={8}>
      <Paper className={classes.root}>
        <Button
          key="close"
          aria-label="Close"
          color="inherit"
          className={classes.close}
          onClick={e => openMenu('dude', e)}
        >
          <ExpandMore />
        </Button>
        <Menu
          id={`dude`}
          key="menu"
          anchorEl={anchorEls.dude}
          open={Boolean(anchorEls.dude)}
          onClose={e => handleClose('dude', e)}
        >
          <MenuItem onClick={e => handleClose('dude', e)}>Delete</MenuItem>
          <MenuItem onClick={e => handleClose('dude', e)}>Flag</MenuItem>
          <MenuItem onClick={e => handleClose('dude', e)}>
            Mark Answered
          </MenuItem>
        </Menu>
        <Table className={classes.table}>
          <TableHead>
            <TableRow>
              <CustomTableCell>Question</CustomTableCell>
              <CustomTableCell numeric>Rating</CustomTableCell>
              <CustomTableCell>Upvote</CustomTableCell>
              <CustomTableCell>Downvote</CustomTableCell>
              <CustomTableCell>Options</CustomTableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            <TableRow className={classes.row} key={n.key}>
              <CustomTableCell ponent="th" scope="row">
                {n.text}
              </CustomTableCell>
              <CustomTableCell numeric>{n.rating}</CustomTableCell>
              <CustomTableCell>
                <IconButton
                  key="close"
                  aria-label="Close"
                  color="inherit"
                  className={classes.close}
                  onClick={() => ''}
                >
                  <ExpandLess />
                </IconButton>
              </CustomTableCell>
              <CustomTableCell>
                <IconButton
                  key="close"
                  aria-label="Close"
                  color="inherit"
                  className={classes.close}
                  onClick={() => ''}
                >
                  <ExpandMore />
                </IconButton>
              </CustomTableCell>
              <CustomTableCell>
                <Button
                  key="close"
                  aria-label="Close"
                  color="inherit"
                  className={classes.close}
                  onClick={e => openMenu(n.key, e)}
                >
                  <ExpandMore />
                </Button>
                <Menu
                  id={`simple-menu-${n.key}`}
                  key="menu"
                  anchorEl={anchorEls[n.key]}
                  open={Boolean(anchorEls[n.key])}
                  onClose={e => handleClose(n.key, e)}
                >
                  <MenuItem onClick={e => handleClose(n.key, e)}>
                    Delete
                  </MenuItem>
                  <MenuItem onClick={e => handleClose(n.key, e)}>dude</MenuItem>
                  <MenuItem onClick={e => handleClose(n.key, e)}>choc</MenuItem>
                </Menu>
              </CustomTableCell>
            </TableRow>
          </TableBody>
        </Table>
      </Paper>
    </Grid>
  );
};

Questions.propTypes = {
  data: PropTypes.object.isRequired,
  anchorEls: PropTypes.object.isRequired,
  classes: PropTypes.object.isRequired,
  openMenu: PropTypes.func.isRequired,
  handleClose: PropTypes.func.isRequired,
};

Questions.defaultProps = {};

export default withStyles(styles)(Questions);

This is working, however the menu is not appearing in the correct place, even when passing in the related event e. I put in a dummy element before the table to test whether or not the table was affecting the menu, and found that the dummy worked just fine, as you can see in the screenshot below.

And the improperly placed menu from the button in the table:

Any ideas on what could be happening? Obviously, the context and anchorEl isn't correctly identifying the location on the page, but not sure what to do to bat that.

Share Improve this question edited Jul 27, 2018 at 23:39 Dane Jordan asked Jul 27, 2018 at 22:43 Dane JordanDane Jordan 1,1391 gold badge17 silver badges28 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

Problem in your openMenu function.You need to set the event target in your openMenu function, and set null in handleClose function. I am giving here a little example which may help you:

class DemoList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [],
            anchorEls: []
        }
    }
    handleActionClick = (id, event) => {
        let { anchorEls } = this.state;
        anchorEls[id] = event.target;
        this.setState({ anchorEls });
    }
    handleActionClose = (id, event) => {
        let { anchorEls } = this.state;
        anchorEls[id] = null;
        this.setState({ anchorEls });
    }
    render() {
        let { classes } = this.props;
        const { data, anchorEls } = this.state;
        return (
            <Paper className="main">
                <Table className={classes.table} aria-label="simple table">
                    <TableHead>
                        <TableRow>
                            <TableCell>Dessert (100g serving)</TableCell>
                            <TableCell align="right">Calories</TableCell>
                            <TableCell align="right">Fat&nbsp;(g)</TableCell>
                            <TableCell align="right">Carbs&nbsp;(g)</TableCell>
                            <TableCell align="right">Action</TableCell>
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {data.map(row => (
                            <TableRow key={row.id}>
                                <TableCell ponent="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">
                                    <IconButton
                                        aria-label="more"
                                        aria-controls="long-menu"
                                        aria-haspopup="true"
                                        onClick={e => this.handleActionClick(row.id, e)}
                                    >
                                        <MoreVert />
                                    </IconButton>
                                    <Menu
                                        id={row.id}
                                        anchorEl={anchorEls[row.id]}
                                        keepMounted
                                        open={Boolean(this.state.anchorEls[row.id])}
                                        onClose={e => this.handleActionClose(row.id, e)}
                                    >
                                        <MenuItem onClick={e => this.handleActionClose(row.id, e)}> View Details </MenuItem>
                                        <MenuItem onClick={e => this.handleActionClose(row.id, e)}> Assign </MenuItem>
                                    </Menu>
                                </TableCell>
                            </TableRow>
                        ))}
                    </TableBody>
                </Table>
            </Paper>
        )
    }
}

After hacking away I found that removing the CustomTableCell declaration and changing all the CustomTableCells to normal TableCells resolved the problem.

本文标签: javascriptEmbedding a Menu inside a TableCell with MaterialUIStack Overflow