Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent event propagation on row click and dialog in material ui

I'm using material-ui and I have a table with a button inside. The button opens a Dialog and I need to be able to support clicking on the table row.
The problem is that with Portals (in react) - the events are propagated, so clicking inside the Dialog (that was opened after clicking on the button) - the click event on the table-row will get fired.

This is the row:

<TableRow onClick={rowClick}>
  <TableCell>Content 1</TableCell>
  <TableCell>Row clicked {count} times</TableCell>
  <TableCell>
    <MyDialog />
  </TableCell>
</TableRow>

This is the dialog:

<>
  <IconButton onClick={handleClickOpen}>
    <EditIcon />
  </IconButton>
  <Dialog disableBackdropClick open={open} onClose={handleClose}>
    <DialogTitle>Dialog</DialogTitle>
    <DialogContent>Some content</DialogContent>
    <DialogActions>
      <Button onClick={handleClose}>Cancel</Button>
      <Button onClick={handleClose}>Save</Button>
    </DialogActions>
  </Dialog>
</>

Here is a working example:
https://codesandbox.io/s/dazzling-hofstadter-gzwll

And this is an animated gif that shows the issue:
enter image description here

I know I can set the "rowClick" on each cell (and leave the last cell without it) but this is just an example and I'm looking for a more generic solution.

like image 986
Dekel Avatar asked Feb 27 '20 15:02

Dekel


People also ask

How will you prevent event from being propagated?

stopPropagation() – It prevents the event from propagating (or “bubbling up”) the DOM.

How do you stop click event propagation in react?

event.stopPropagation() This will stop any parent component's event from firing. To use this: Make sure to pass the event object as a parameter. Use the stopPropagation method on the event object above your code within your event handler function.

How do you stop a synthetic event propagation?

React Stop Propagation on jQuery EventUse Event. stopImmediatePropagation to prevent your other (jQuery in this case) listeners on the root from being called. It is supported in IE9+ and modern browsers.

Which event can be used to stop event propagation in react?

14, returning false from an event handler will no longer stop event propagation. Instead, e. stopPropagation() or e. preventDefault() should be triggered manually, as appropriate.


2 Answers

It took some time to find a proper solution, but the only way to prevent the propagation of the event was to add a "click" function on the dialog itself:

<>
  <IconButton onClick={handleClickOpen}>
    <EditIcon />
  </IconButton>
  <Dialog
    disableBackdropClick
    open={open}
    onClose={handleClose}
    onClick={handleDialogClick}
  >
    <DialogTitle>Dialog</DialogTitle>
    <DialogContent>Some content</DialogContent>
    <DialogActions>
      <Button onClick={handleClose} color="primary">
        Cancel
      </Button>
      <Button onClick={handleClose} color="primary">
        Save
      </Button>
    </DialogActions>
  </Dialog>
</>

And have the handleClickDialog function stop the event propagation:

const handleDialogClick = e => {
  e.stopPropagation();
}; 

Here is a working example:
https://codesandbox.io/s/cocky-violet-19uvd

like image 190
Dekel Avatar answered Nov 13 '22 12:11

Dekel


One option is to add an onClick handler within my-dialog.js.

const handleClick = e => {
    e.stopPropagation();
    // doesn't do anything except stop the event
  };

and then add it to your Dialog:

     <Dialog
        disableBackdropClick
        open={open}
        onClose={handleClose}
        onClick={handleClick}
      >

Fork of your sandbox with the changes: https://codesandbox.io/s/nostalgic-chaplygin-lql5m?fontsize=14&hidenavigation=1&theme=dark

like image 38
WGriffing Avatar answered Nov 13 '22 13:11

WGriffing