Home > Blockchain >  Open a modal (or dialogue) from a dropdown asking the user if they would like to take an action
Open a modal (or dialogue) from a dropdown asking the user if they would like to take an action

Time:10-07

I would like to open a modal (or dialogue) when a user selects an option from a dropdown menu.

Eventually there will be a few options in the dropdown, and different dialogues/modals will be called and rendered depending on which dropdown option has been clicked. For now - how do I get the modal/dialogue to open with dropdown menu events?

I'm currently using the handleClose handler to attempt to open a dialogue since that event should be easy to grab and use right out of the docs for MUI Menu and MenuItem.

The origination call to the DropdownMenu component (which works well and shows the dropdown menu) occurs in a table through the click of an icon

<DropdownMenu options={['Show modal or dialogue to the user']}>
    <MoreHorizIcon />
</DropdownMenu>

The DropdownMenu component (also working well itself, except for not triggering the dialogue/modal) looks like this

interface IProps extends Omit<unknown, 'children'> {
    children: any;
    options: string[];
}

const ITEM_HEIGHT = 48;

const DropdownMenu = ({ children, options }: IProps) => {
    const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
    const open = Boolean(anchorEl);
    const handleClick = (event: React.MouseEvent<HTMLElement>) => {
        setAnchorEl(event.currentTarget);
    };

    const showModal = () => {
        return (
            <AlertDialog />
        )
    }
    const handleClose = () => {
        //the native alert dialogue works well
        alert('I want to show a dialog or modal the same way this alert shows up and ask the user if they are sure they want to delete something')
        //why isn't the custom alert dialog being called?
        showModal();
        setAnchorEl(null);
    };

    return (
        <div>
            <IconButton
                aria-label="more"
                id="more-button"
                aria-controls="long-menu"
                aria-expanded={open ? 'true' : undefined}
                aria-haspopup="true"
                onClick={handleClick}
            >
                {children}
            </IconButton>
            <Menu
                id="dropdownmenu"
                MenuListProps={{
                    'aria-labelledby': 'more-button'
                }}
                anchorEl={anchorEl}
                open={open}
                onClose={handleClose}
                PaperProps={{
                    style: {
                        maxHeight: ITEM_HEIGHT * 4.5,
                        width: '20ch'
                    }
                }}
            >

                {options.map(option => (
                    <MenuItem key={option} onClick={handleClose} >
                        {option}
                    </MenuItem>
                ))}
            </Menu>
        </div>
    );
};

export default DropdownMenu;

And the example starter dialogue I am using to get the ball rolling looks like this

const AlertDialog = () => {
    const [open, setOpen] = React.useState(true);
    const handleClose = () => {
        setOpen(false);
    };
    return (
        <div>
            <Dialog
                open={open}
                onClose={handleClose}
                aria-labelledby="alert-dialog-title"
                aria-describedby="alert-dialog-description"
            >
                <DialogTitle id="alert-dialog-title">
                    {"Sweet Filler Dialog"}
                </DialogTitle>
                <DialogContent>
                    <DialogContentText id="alert-dialog-description">
                        Are you sure?
                    </DialogContentText>
                </DialogContent>
                <DialogActions>
                    <Button onClick={handleClose}>NO</Button>
                    <Button onClick={handleClose} autoFocus>
                        YES
                    </Button>
                </DialogActions>
            </Dialog>
        </div>
    );
}

CodePudding user response:

You can use a state variable to trigger the modal in the DropdownMenu component, whenever you wanted to show the dialog/modal.

const [isModalOpen, setIsModalOpen] = React.useState(false);

and then in the handleClose, you can update the modal state to open the modal.

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

Then somewhere in your JSX of DropdownMenu, you can conditionally render the AlertDialog component like this

{isModalOpen ? <AlertDialog open={isModalOpen} setOpen={setIsModalOpen} /> : null}

Finally, update your AlertDialog component to use props to handle the closing of the modal.

const AlertDialog = ({ open, setOpen }) => {
  const handleClose = () => {
    setOpen(false);
  };
  return (
    <div>
        <Dialog
            open={open}
            onClose={handleClose}
            aria-labelledby="alert-dialog-title"
            aria-describedby="alert-dialog-description"
        >
            <DialogTitle id="alert-dialog-title">
                {"Sweet Filler Dialog"}
            </DialogTitle>
            <DialogContent>
                <DialogContentText id="alert-dialog-description">
                    Are you sure?
                </DialogContentText>
            </DialogContent>
            <DialogActions>
                <Button onClick={handleClose}>NO</Button>
                <Button onClick={handleClose} autoFocus>
                    YES
                </Button>
            </DialogActions>
        </Dialog>
    </div>
  );
}
  • Related