0

I want to use a dialog box of material UI. I am navigating that dialog box from the right side menu(sidebars -> user registration), using another component. I just want to open that dialog box on the current page home or about us. It is a user registration dialog. Can you help on that?

When I tried to open the user registration dialog, I am unable to open the dialog box in the current page, that's why I have created a separate component for the dialog box component.

I want to open that dialog when I select the side menu option. The dialog box should be open in the current page.

This is the code sandbox link. https://codesandbox.io/s/immutable-sound-ggj4w

App js

import React from "react";
import "./styles.css";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Home from "./home";
import About from "./about";
import Dialog from "./dialog";
import SideMenu from "./sidemu";
export default function App() {
  return (
    <div className="App">
      <BrowserRouter>

      <SideMenu />
        {/* <Switch> */}
          <Route exact path="/" component={Home} />
          <Route exact path="/about" component={About} />
          <Route exact path="/sidemenu" component={SideMenu} />
          <Route exact path="/dialog" component={Dialog} />
        {/* </Switch> */}
      </BrowserRouter>
      {/* <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2> */}
    </div>
  );
}

home js

import React, { Component } from "react";

class Home extends Component {
  render() {
    return (
      <div>
        <div>Home</div>
      </div>
    );
  }
}

export default Home;

about us

import React, { Component } from "react";

class Home extends Component {
  render() {
    return (
      <div>
        <div>about us</div>
      </div>
    );
  }
}

export default Home;

dialog js

import React from 'react';
import Button from '@material-ui/core/Button';
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';

export default function AlertDialog() {
  const [open, setOpen] = React.useState(false);

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

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

  return (
    <div>
      <Button variant="outlined" color="primary" onClick={handleClickOpen}>
        Open alert dialog
      </Button>
      <Dialog
        open={true}
        onClose={handleClose}
        aria-labelledby="alert-dialog-title"
        aria-describedby="alert-dialog-description"
      >
        <DialogTitle id="alert-dialog-title">{"Use Google's location service?"}</DialogTitle>
        <DialogContent>
          <DialogContentText id="alert-dialog-description">
            Let Google help apps determine location. This means sending anonymous location data to
            Google, even when no apps are running.
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleClose} color="primary">
            Disagree
          </Button>
          <Button onClick={handleClose} color="primary" autoFocus>
            Agree
          </Button>
        </DialogActions>
      </Dialog>
    </div>
  );
}

sidemenu js

import React from 'react';
import './styles.css';
import { Link } from 'react-router-dom';
import { makeStyles } from '@material-ui/core/styles';
import Drawer from '@material-ui/core/Drawer';
import { List, ListItemIcon, ListItem, ListItemText } from '@material-ui/core';
import MenuRoundedIcon from '@material-ui/icons/MenuRounded';
import HomeRoundedIcon from '@material-ui/icons/HomeRounded';
import MenuBookRoundedIcon from '@material-ui/icons/MenuBookRounded';

const useStyles = makeStyles({
  list: {
    width: 250,
  },
  fullList: {
    width: 'auto',
  },
});

export default function TemporaryDrawer() {
  const classes = useStyles();
  const [state, setState] = React.useState({
    top: false,
    left: false,
    bottom: false,
    right: false,
  });

  const toggleDrawer = (side, open) => event => {
    if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
      return;
    }

    setState({ ...state, [side]: open });
  };

  const sideList = side => (
    <div
      className={classes.list}
      role="presentation"
      onClick={toggleDrawer(side, false)}
      onKeyDown={toggleDrawer(side, false)}
    >
      <List>
        <Link className="right-menu-data" to="/">
          <ListItem button>
            <ListItemIcon>
              <HomeRoundedIcon />
            </ListItemIcon>
            <ListItemText>Home</ListItemText>
          </ListItem>
        </Link>
        <Link className="right-menu-data" to="/about"><ListItem button>
          <ListItemIcon>
            <MenuBookRoundedIcon />
          </ListItemIcon>
          <ListItemText>About us</ListItemText>
        </ListItem>
        </Link>
        <Link className="right-menu-data" to="/dialog"><ListItem button>
          <ListItemIcon>
            <MenuBookRoundedIcon />
          </ListItemIcon>
          <ListItemText>User Registration</ListItemText>
        </ListItem>
        </Link>
      </List>


    </div>
  );


  return (
    <div>
      <MenuRoundedIcon className="careerpedia-menu-bars" onClick={toggleDrawer('right', true)} />
      <Drawer anchor="right" open={state.right} onClose={toggleDrawer('right', false)}>
        {sideList('right')}
      </Drawer>
    </div>
  );
}
Manu Panduu
  • 411
  • 1
  • 9
  • 17
  • Could you explain what really you want to achieve – Rahul Raj Mar 09 '20 at 09:02
  • i want to open dialog(user registration form) using side menu...of options like (parent registration, student registration). that dialog box should be in current url... – Manu Panduu Mar 09 '20 at 09:13

1 Answers1

1

One way to achieving this is to factor the logic to open/close the modal out of the dialog component to a "central" location, preferably in the app, but outside the router. This allows the dialog to be opened/closed from a single location by callbacks that can be passed around the app, and not be coupled to any specific route your app is on.

A quick refactoring of your code:

dialog.js

const AlertDialog = ({ open, onAgree, onClose, onDisagree }) => (
  <Dialog
    open={open}
    onClose={onClose}
    aria-labelledby="alert-dialog-title"
    aria-describedby="alert-dialog-description"
  >
    <DialogTitle id="alert-dialog-title">
      {"Use Google's location service?"}
    </DialogTitle>
    <DialogContent>
      <DialogContentText id="alert-dialog-description">
        Let Google help apps determine location. This means sending anonymous
        location data to Google, even when no apps are running.
      </DialogContentText>
    </DialogContent>
    <DialogActions>
      <Button onClick={onDisagree} color="primary">
        Disagree
      </Button>
      <Button onClick={onAgree} color="primary" autoFocus>
        Agree
      </Button>
    </DialogActions>
  </Dialog>
);

App.js

export default function App() {
  const [open, setOpen] = useState(false);

  const openDialog = () => setOpen(true);
  const closeDialog = () => setOpen(false);

  const onAgreeHandler = () => {
    closeDialog();
    alert("AGREED");
  };
  const onDisgreeHandler = () => {
    closeDialog();
    alert("DISAGREED");
  };
  const onCloseHandler = (event, reason) => {
    closeDialog();
    alert(`Dialog closed. Reason: ${reason}`);
  };

  return (
    <div className="App">
      <BrowserRouter>
        <SideMenu openDialog={openDialog} /> // Pass dialog open callback to sidemenu
        <Route exact path="/" component={Home} />
        <Route exact path="/about" component={About} />
        <Route exact path="/dialog" component={Dialog} />
      </BrowserRouter>

      <Button variant="outlined" color="primary" onClick={openDialog}>
        Open alert dialog test
      </Button>

      <Dialog
        open={open}
        onAgree={onAgreeHandler}
        onClose={onCloseHandler}
        onDisagree={onDisgreeHandler}
      />
    </div>
  );
}

sidemu.js

export default function TemporaryDrawer({ openDialog }) { // Accept openDialog callback

  ...
    { /* Add new menu list item (not in a Link!) */ }
    <ListItem button onClick={openDialog}> // Set onClick handler to openDialog callback
      <ListItemIcon>
        <MenuBookRoundedIcon />
      </ListItemIcon>
      <ListItemText>Trigger dialog?</ListItemText>
    </ListItem>

Edit dreamy-ride-qx5co

NOTE: As your app grows in size/complexity this pattern may become a little unwieldy (if you need to open a dialog by any further descendants) and you'll likely want to switch to using a react context provider/consumer specifically for the dialog, or use a state management system like Redux so you can dispatch simple actions to open/close it.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Thanks very much....is there any possible to work without alert box... – Manu Panduu Mar 11 '20 at 12:44
  • sorry...i have asked one more question in stackover flow.....please see this also.....https://stackoverflow.com/questions/60636396/convert-functional-component-to-class-component-in-react-js/60636489#60636489.......................... – Manu Panduu Mar 11 '20 at 12:59
  • @ManuPanduu Yes, you can do whatever you please. That was just to demo how to handle each scenario of interacting with the dialog. – Drew Reese Mar 11 '20 at 14:15