Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign which MenuItems open onClick when multiple Menus are present on the material-ui Appbar using React?

I created an AppBar with a menu based on the examples given on the material UI site and it works fine with one menu. But when I try adding a second dropdown menu, on clicking either icon, I get the same set of MenuItems showing up as seen in the image.

Here is the list of menu items that are showing up when either icon is clicked

import React, { Component } from 'react';

// Material UI Imports
import { withStyles } from 'material-ui/styles';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import Typography from 'material-ui/Typography';
import Button from 'material-ui/Button';
import IconButton from 'material-ui/IconButton';
import Tooltip from 'material-ui/Tooltip';
import Menu, { MenuItem } from 'material-ui/Menu';

import PeopleIcon from 'material-ui-icons/People';
import ViewListIcon from 'material-ui-icons/ViewList';
import CompareArrowsIcon from 'material-ui-icons/CompareArrows';

const styles = {
  root: {
    width: '100%',
  },
  flex: {
    flex: 1,
  },
  menuItem: {
    paddingLeft: '10px'
  }
}

class Header extends Component {
  constructor(props) {
    super(props);

    this.state = { anchorEl: null };
  }

  handleMenu = event => {
    console.log(event.currentTarget);
    this.setState({ anchorEl: event.currentTarget });
  }

  handleClose = () => {
    this.setState({ anchorEl: null });
  }

  render() {
    const { classes } = this.props;
    const { anchorEl } = this.state;
    const open = Boolean(anchorEl);

    return(
      <div className={classes.root}>
        <AppBar position="static">
          <Toolbar>
            <Typography type="title" color="inherit" className={classes.flex}>
              New Faces
            </Typography>

            {/* Menu Item One */}
            <div>
              <Tooltip title="Lists" className={classes.menuItem}>
                <IconButton
                  color="inherit"
                  aria-owns={open ? 'menu-list' : null}
                  aria-haspopup="true"
                  onClick={this.handleMenu}
                >
                  <ViewListIcon />
                </IconButton>
              </Tooltip>

              <Menu
                id="menu-list"
                anchorEl={anchorEl}
                anchorOrigin={{
                  vertical: 'top',
                  horizontal:'right',
                }}
                transformOrigin={{
                  vertical: 'top',
                  horizontal:'right',
                }}
                open={open}
                onClose={this.handleClose}
              >
                <MenuItem onClick={this.handleClose}>Create List</MenuItem>
                <MenuItem onClick={this.handleClose}>List 1</MenuItem>
                <MenuItem onClick={this.handleClose}>List 2</MenuItem>
              </Menu>
            </div>

            {/* Menu Item Two */}
            <div>
              <Tooltip title="User Management" className={classes.menuItem}>
                <IconButton
                  color="inherit"
                  aria-owns={open ? 'menu-appbar' : null}
                  aria-haspopup="true"
                  onClick={this.handleMenu}
                >
                  <PeopleIcon />
                </IconButton>
              </Tooltip>

              <Menu
                id="menu-appbar"
                anchorEl={anchorEl}
                anchorOrigin={{
                  vertical: 'top',
                  horizontal:'right',
                }}
                transformOrigin={{
                  vertical: 'top',
                  horizontal:'right',
                }}
                open={open}
                onClose={this.handleClose}
              >
                <MenuItem onClick={this.handleClose}>Profile</MenuItem>
                <MenuItem onClick={this.handleClose}>User Management</MenuItem>
                <MenuItem onClick={this.handleClose}>Logout</MenuItem>
              </Menu>
            </div>
          </Toolbar>
        </AppBar>
      </div>
    );
  }
}

export default withStyles(styles)(Header);

How do you assign which MenuItems show up according to the icon that is clicked? I assumed it was supposed to show the MenuItems that are directly under the selected anchorEl. Any help would be much appreciated!

like image 758
Glen Padua Avatar asked Jan 09 '18 13:01

Glen Padua


1 Answers

Check this working solution https://codesandbox.io/s/84xl2v8wm2 I whipped up

What I have done is extract the common code into a separate component lets call it MenuButton and use it at multiple places. So that each menu button has its own scope, own event handlers etc. Currently, the issue is that you are using same event handlers for two different elements and using the same variable to keep track of the state of the menu. Either use two variables like open and open1 or extract the code into a separate component like I have done.

Parent file

<MenuButton iconType={AccountCircle} items={['Create','List1', 'List2']}/>
<MenuButton iconType={MenuIcon} items={['Profile','User Management', 'Logout']}/>

menuButton.js file

import React from 'react';
import AccountCircle from 'material-ui-icons/AccountCircle';
import Menu, { MenuItem } from 'material-ui/Menu';
import IconButton from 'material-ui/IconButton';
import { withStyles } from 'material-ui/styles';

class MenuButton extends React.Component {
  state = {
    anchorEl: null
  };

  handleChange = (event, checked) => {
    this.setState({ auth: checked });
  };

  handleMenu = event => {
    this.setState({ anchorEl: event.currentTarget });
  };

  handleClose = () => {
    this.setState({ anchorEl: null });
  };

  render() {
    const { classes } = this.props;
    const { auth, anchorEl } = this.state;
    const open = Boolean(anchorEl);
    const Wrapper = this.props.iconType;
    const listItems = this.props.items.map((link) =>
      <MenuItem onClick={this.handleClose} >{link}</MenuItem>
    );

    return (
      <div>
        <IconButton
          aria-owns={open ? 'menu-appbar' : null}
          aria-haspopup="true"
          onClick={this.handleMenu}
          color="contrast"
        >
          {<Wrapper />}
        </IconButton>
        <Menu
          id="menu-appbar"
          anchorEl={anchorEl}
          anchorOrigin={{
            vertical: 'top',
            horizontal: 'right',
          }}
          transformOrigin={{
            vertical: 'top',
            horizontal: 'right',
          }}
          open={open}
          onClose={this.handleClose}
        >
        {listItems}


        </Menu>
      </div>
    );
  }

}

export default MenuButton;
like image 178
cdoshi Avatar answered Sep 29 '22 17:09

cdoshi