Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open Material UI Dialogs from Parent Component?

I need to open two seperate Material UI dialogs (Terms & Privacy) from their parent component which is a material UI 'simple menu'. I have them imported and nested in the parent already, I just don't know how to get them to open from their parent while being seperate files. I played around with this similar question for way too long but couldn't get it working. Thanks.

Parent component (Menu):

import React from 'react';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import IconButton from '@material-ui/core/IconButton';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import Terms from './Terms';
import Privacy from './Privacy'

const More = () => {
  const [anchorEl, setAnchorEl] = React.useState(null);

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

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

  return (
    <div>
      <IconButton
        aria-label="more"
        aria-controls="simple-menu"
        aria-haspopup="true"
        onClick={handleClick}
        edge='end'
      >
        <MoreVertIcon />
      </IconButton>
      <Menu
        id="simple-menu"
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        <MenuItem onClick={handleClose}>Terms of Use</MenuItem>
        <MenuItem onClick={handleClose}>Privacy Policy</MenuItem>
      </Menu>
      <Terms />
      <Privacy />
    </div>
  );
}

export default More;

Child component 1 ('Terms' dialog):

import React from 'react';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import Button from '@material-ui/core/Button';

const Terms = () => {

  const [openTerms, setOpen] = React.useState(false);

  const openTermsDialog = () => {
    setOpen(true);
  };

  const handleCloseTerms = () => {
    setOpen(false);
  };

  return (
    <Dialog
      open={openTerms}
      onClose={handleCloseTerms}
      aria-labelledby="terms-dialog-title"
      aria-describedby="terms-dialog-description"
    >
      <DialogTitle id="terms-dialog-title">{"Terms of Use"}</DialogTitle>
      <DialogContent>
        <DialogContentText id="terms-dialog-description">
          Terms go here
        </DialogContentText>
      </DialogContent>
      <DialogActions>
        <Button onClick={handleCloseTerms} color="primary" autoFocus>
          Agree
        </Button>
      </DialogActions>
    </Dialog>
  )
}

export default Terms;

Child component 2 ('Privacy' dialog):

import React from 'react';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import Button from '@material-ui/core/Button';

const Privacy = () => {

  const [openPrivacy, setOpen] = React.useState(false);

  const handleOpenPrivacy = () => {
    setOpen(true);
  };

  const handleClosePrivacy = () => {
    setOpen(false);
  };

  return (
    <Dialog
      open={openPrivacy}
      onClose={handleClosePrivacy}
      aria-labelledby="privacy-dialog-title"
      aria-describedby="privacy-dialog-description"
    >
      <DialogTitle id="alert-dialog-title">{"Privacy Policy"}</DialogTitle>
      <DialogContent>
        <DialogContentText id="privacy-dialog-description">
         Privacy policy goes here
        </DialogContentText>
      </DialogContent>
      <DialogActions>
        <Button onClick={handleClosePrivacy} color="primary" autoFocus>
          Agree
        </Button>
      </DialogActions>
    </Dialog>
  )
}

export default Privacy;
like image 462
benmneb Avatar asked May 21 '20 09:05

benmneb


People also ask

What is a material-UI dialog?

It is actually composed the following Material-UI components: a Backdrop, a Container (sort of), and Paper. These construct a Dialog component and should not be confused with the children components that can be passed such as DialogContent or DialogTitle. We can see these components reflected in the DOM elements in the screenshot above.

How to get data from parent component when modal is closed?

In the dialogRef we are saving the Modal instance to subscribe its callback method afterClosed () which will return data back to parent component when modal is closed. Now we will update the Dialog Modal template and class to accept data from Parent, show it in the modal.

What is Dialog model in Angular Material UI?

The dialog models are used to create a focused area on-screen generally used for data actions like Create, Update data or show alerts and confirmation. The Angular Material UI library provides a number of components which can be used by importing the required APIs in the project modules.

How to open the dialog modal from the app component?

Note: For Angular CLI versions before 8, we will need to add the MyDialogModalComponent in the entryComponents Array in the app's module as Dialog is loaded dynamically after app load. To open the dialog modal from the App component, we will add an input field and a button with a (click) event calling the openDialog () method.


1 Answers

Just lift up the state from the dialog components to the parent component, and pass it down to the child components.

  const More = () => {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const [openDialogName, setOpenDialog] = React.useState(null);

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

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

  const openTermsDialog = () => {
    setOpenDialog('TERMS');
    handleClose();
  };

  const openPrivacyDialog = () => {
    setOpenDialog('PRIVACY');
    handleClose();
  };

  const closeDialog = () => {
    setOpenDialog(null);
  };

  return (
    <div>
        {/* ... */}
        <MenuItem onClick={openTermsDialog}>Terms of Use</MenuItem>
        <MenuItem onClick={openPrivacyDialog}>Privacy Policy</MenuItem>
        {/* ... */}
      <Terms open={openDialogName === 'TERMS'} onClose={closeDialog} />
      <Privacy open={openDialogName === 'PRIVACY'} onClose={closeDialog} />
    </div>
  );
}

export default More;

And in Privacy for example (and the same idea for Terms as well):

const Privacy = ({ open, onClose }) => {
  return (
    <Dialog
      open={open}
      onClose={onClose}
    >
    {/* ... */}
  );
};
like image 176
Martin Avatar answered Oct 20 '22 08:10

Martin