Extelliqent
Extelliqent

Reputation: 1858

React Display Separate Popover Component on Menu Click

I have the below menu:

enter image description here

So, ideally you'd click on those 3 dots which would open up another box next to it, I decided to use a popover(https://material-ui.com/components/popover/).. The problem is that when you click the 3 dots nothing happens. I assume this is because onClick function returns a functional popover component but that doesn't get displayed. I put in debuggers and alerts inside the functional component no hit at all.

This is those 3 dots

 <IconButton
        aria-describedby="simple-popover"
        variant="contained"
        onClick={e => this.moreClick(e, props.children)}
      >
        <More />
      </IconButton>

This is moreClick function

  moreClick = (e, officeAccount) => {
    return (
      <AccountFavoritesPopover element={e} officeAccount={officeAccount} />
    );
  };

This is the whole popover

import React from "react";
import Popover from "@material-ui/core/Popover";

export default function AccountFavoritesPopover(element, officeAccount) {
  const anchorEl = element;
  const open = Boolean(anchorEl);
  const id = open ? "simple-popover" : undefined;

  return (
    <div>
      <Popover
        id={id}
        open={open}
        anchorEl={anchorEl}
        //onClose={alert}
        anchorOrigin={{
          vertical: "top",
          horizontal: "right"
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "left"
        }}
      >
        <div>{officeAccount}</div>
      </Popover>
    </div>
  );
}

Does popover have to be inside the main file? Currently the 3 dots is in the main file and AccountFavoritesPopover is a whole separate file.

I attempted to put "AccountFavoritesPopover" code inside the main file but I cannot utilize useState in the main file because it's a class. Also, I cannot convert it to actual state and use setState because once setState kicks in, the menu will disappear...

Edit: Below is the Menu

<Creatable
  id="Select"
  menuIsOpen={this.state.Focused}
  components={{
    Option: this.Option
  }}
/>

Below is the Options inside menu

<div style={{ position: "relative" }}>
        <components.Option {...props} />
        <div id="MoreBox">
          <IconButton
            aria-describedby="simple-popover"
            variant="contained"
            onClick={e => this.moreClick(e, props.children)}
          >
            <More />
          </IconButton>
        </div>
      </div>

Upvotes: 0

Views: 2884

Answers (1)

Nagesh Dhope
Nagesh Dhope

Reputation: 837

Try this, this should work(Not tested)

Main.js

export default class Main extends Component {
    constructor(props) {
        this.state = {
            selectedIndex: 0,
            selectedId: 0,
            anchorEl: null
        };
    }

    moreClick = (anchorEl, selectedId, selectedIndex) => {
        this.setState({
            selectedId,
            selectedIndex,
            anchorEl,
            open: true,
        });
    }

    handleClose = () => {
        this.setState({
            open: false
        });
    }

    render() {
        const menu = [
            {
                id: 1,
                text: '002',
                more: 'more 003'
            },
            {
                id: 2, 
                text: '003',
                more: 'more 003'
            },
            {
                id: 3, 
                text: '004',
                more: 'more 003'
            }
        ]

        const menuDom = menu.map((m, index) => {
            return (
                <IconButton
                    key={m.id}
                    aria-describedby="simple-popover"
                    variant="contained"
                    onClick={e => this.moreClick(e.currentTarget, index, m.id)}>
                        {m.text}
                </IconButton>
            )
        })
        const more = (<More>{menu[this.state.selectedIndex].text}</More>)
        return (
            <div>
                {menuDom}
                <AccountFavoritesPopover open={this.state.open} anchorEl={this.state.anchorEl} onClose={this.handleClose}>
                    {more}
                </AccountFavoritesPopover>
            </div>
        )
    }
}

AccountFavoritesPopover.js

export default function AccountFavoritesPopover(open, anchorEl, onClose) {
    const id = open ? "simple-popover" : undefined;

    return (
      <div>
        <Popover
          id={id}
          open={open}
          anchorEl={anchorEl}
          onClose={onClose}
          anchorOrigin={{
            vertical: "top",
            horizontal: "right"
          }}
          transformOrigin={{
            vertical: "top",
            horizontal: "left"
          }}
        >
          <div>{this.props.children}</div>
        </Popover>
      </div>
    );
  }

Upvotes: 1

Related Questions