Handling multiple MenuItems in material-ui React

Viewed 1463

enter image description herePlease help me with this multiple menu handling events. I have dynamic menus and its corresponding menuitems in a json. I wanted to show menuitems declared under that particular parent menu, instead it is overlapping and showing all of the parents menuitems when a single menu button is clicked. This is my Nvbar.js

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Toolbar from '@material-ui/core/Toolbar';
import Button from '@material-ui/core/Button';
import { InputData } from '../InputJSON';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';


const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
  },
  navButton: {
    margin: 'auto',
  },
  title: {
    flexGrow: 1,
  },
  toolbar:{
    backgroundColor: "orange",
  },
}));



export default function ButtonAppBar() {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = React.useState(null);

  const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <div className={classes.root}>
        <Toolbar className={classes.toolbar}>
          {Object.keys(InputData).map((item, index) => (
              <div 
                className={classes.navButton}
                key={index}
              >
                <Button 
                  color="inherit"
                  onClick={handleClick}
                >
                  {item} <i className='fas fa-caret-down' />
                </Button>
                <Menu
                  anchorEl={anchorEl}
                  keepMounted
                  open={Boolean(anchorEl)}
                  onClose={handleClose}
                  getContentAnchorEl={null}
                  anchorOrigin={{vertical: 'bottom', horizontal: 'center'}}
                  transformOrigin={{vertical: 'top', horizontal: 'center'}}
                >
                  {InputData[item].map((menuitems, menuindex) =>
                     (
                        <MenuItem
                          key={menuindex}
                          selected={menuitems === item}
                          onClick={handleClose}
                        >
                          {menuitems.title}
                        </MenuItem>

                    )
                  )}
                </Menu>
                
              </div>
            ))
          }
        </Toolbar>
    </div>
  );
}

InputData.js

export const MenuItems = 
  {"furniture": 
    [
      {
        title: 'Marketing',
        path: '/marketing',
        cName: 'dropdown-link'
      },
      {
        title: 'Consulting',
        path: '/consulting',
        cName: 'dropdown-link'
      },
      {
        title: 'Design',
        path: '/design',
        cName: 'dropdown-link'
      },
      {
        title: 'Development',
        path: '/development',
        cName: 'dropdown-link'
      }
    ],  
    "mobiles": 
    [
      {
        title: 'iphone',
        path: '/marketing',
        cName: 'dropdown-link'
      },
      {
        title: 'samsung',
        path: '/consulting',
        cName: 'dropdown-link'
      },
      {
        title: 'oneplus',
        path: '/design',
        cName: 'dropdown-link'
      },
      {
        title: 'sony',
        path: '/development',
        cName: 'dropdown-link'
      }
    ],
    "laptops": 
    [
      {
        title: 'iphone',
        path: '/marketing',
        cName: 'dropdown-link'
      },
      {
        title: 'samsung',
        path: '/consulting',
        cName: 'dropdown-link'
      },
      {
        title: 'oneplus',
        path: '/design',
        cName: 'dropdown-link'
      },
      {
        title: 'sony',
        path: '/development',
        cName: 'dropdown-link'
      }
    ],
    "aircon": 
    [
      {
        title: 'iphone',
        path: '/marketing',
        cName: 'dropdown-link'
      },
      {
        title: 'samsung',
        path: '/consulting',
        cName: 'dropdown-link'
      },
      {
        title: 'oneplus',
        path: '/design',
        cName: 'dropdown-link'
      },
      {
        title: 'sony',
        path: '/development',
        cName: 'dropdown-link'
      }
    ],
    "kitapp": 
    [
      {
        title: 'iphone',
        path: '/marketing',
        cName: 'dropdown-link'
      },
      {
        title: 'samsung',
        path: '/consulting',
        cName: 'dropdown-link'
      },
      {
        title: 'oneplus',
        path: '/design',
        cName: 'dropdown-link'
      },
      {
        title: 'sony123',
        path: '/development',
        cName: 'dropdown-link'
      }
    ],
    
  };
1 Answers

You need to track each anchor element separately, according to which menu item has been clicked. You can do this by setting the element according to the item key:

export default function ButtonAppBar() {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = React.useState(null);

  // Instead of tracking a single element, set the element according to
  // the menu item's index.
  const handleClick = (index, event) => {
    setAnchorEl({ [index]: event.currentTarget });
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <div className={classes.root}>
      <Toolbar className={classes.toolbar}>
        {Object.keys(InputData).map((item, index) => (
          <div className={classes.navButton} key={index}>
            <Button color="inherit" onClick={(e) => handleClick(index, e)}>
              {item} <i className="fas fa-caret-down" />
            </Button>
            <Menu
              anchorEl={
                // Check to see if the anchor is set.
                anchorEl && anchorEl[index]
              }
              keepMounted
              open={
                // Likewise, check here to see if the anchor is set.
                Boolean(anchorEl && anchorEl[index])
              }
              onClose={handleClose}
              getContentAnchorEl={null}
              anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
              transformOrigin={{ vertical: "top", horizontal: "center" }}
            >
              {menuItems[item].map((menuitems, menuindex) => (
                <MenuItem
                  key={menuindex}
                  selected={menuitems === item}
                  onClick={handleClose}
                >
                  {menuitems.title}
                </MenuItem>
              ))}
            </Menu>
          </div>
        ))}
      </Toolbar>
    </div>
  );
}

Working sandbox: https://codesandbox.io/s/icy-haze-h0594

Related