如何处理对话框(模态)上的“外部”点击?

问题描述 投票:0回答:11

单击框外时,我的框会关闭,使我丢失所有输入。 我希望仅在单击取消按钮时关闭我的框。 我不确定点击外部时是什么让它关闭。有什么帮助吗?

我正在使用@material-ui/core

  _close() {
        DeviceCreationActions.close();
    }

render() {
        const actions = [
            <Button
                id="device-create-dialog-close"
                key="device-create-dialog-close"
                onClick={this._close}
            >
              {this.context.intl.formatMessage({id: 'Cancel'})}
            </Button>
        ];

        if (0 < this.state.stepIndex) {
            actions.push(<Button
                id="device-create-dialog-back"
                key="device-create-dialog-back"
                onClick={this._previousStep.bind(this)}
              >
                {this.context.intl.formatMessage({id: 'Back'})}
              </Button>
            );
        }

        if (
            (1 >= this.state.stepIndex && 0 < this.state['formStep' + this.state.stepIndex].length) ||
            (0 < this.state.stepIndex)
        ) {
            actions.push(<Button
                id="device-create-dialog-next"
                key="device-create-dialog-next"
                onClick={2 === this.state.stepIndex ? this._save.bind(this) : this._nextStep.bind(this)}
              >
                {this.context.intl.formatMessage({id: 2 === this.state.stepIndex ? 'Create' : 'Next'})}
              </Button>
            );
        }
javascript reactjs dialog modal-dialog material-ui
11个回答
133
投票

disableBackdropClick
在 Material UI v5 中不起作用。

对话框 API(下)

您可以使用迁移指南中的代码,通过检测关闭事件的源,通过

onClose
prop
手动处理每个关闭源。

<Dialog onClose={handleClose} />

并使用处理程序来停止它

const handleClose = (event, reason) => {
    if (reason && reason == "backdropClick") 
        return;
    myCloseModal();
}

68
投票

我认为你需要的是

disableBackdropClick
传递给
<Modal />
组件

<Modal disableBackdropClick />

您还可以使用

disableEscapeKeyDown
属性

禁用按 Esc 键时关闭对话框

19
投票

只需删除

onClose
方法

  <Dialog
     sx={{
       position: 'absolute',
       left: 300,
       top: 35
     }}
     maxWidth="lg"
    open={open}
    // onClose={handleClose}
   .....

4
投票
const handleClose = (event, reason) => {
    if (reason && reason == "backdropClick" && "escapeKeyDown") 
        return;
    myCloseModal();
}

这将防止模态关闭外部点击和退出按钮


3
投票

由于

disableBackdropClick
在最新版本的 Material ui 中已被弃用,因此更简单的方法是从对话框属性中删除
onClose
并在
DialogTitle
上添加一个按钮,并在单击该按钮后触发您的
handleClose
函数将打开对话框的状态设置为 false

<Dialog
  // onClose={handleClose} // the line to be removed
  open={dialog.open}
  fullWidth
  maxWidth="md"
  >
  <DialogTitle
    sx={{
      display: 'flex',
      alignItems: 'center',
    }}
  >
    <Typography
      variant="h5"
      textAlign="center"
      component="h1"
      gutterBottom
      sx={{
        pl: 2,
      }}
    >
      {dialog.action === 'add'
        ? 'Ajouter une question'
        : 'Editer la question'}
    </Typography>
    
    {/*Fire handleClose after a click on close button*/}
    <IconButton onClick={handleClose} sx={{ ml: 'auto' }}>
      <CloseIcon />
    </IconButton>
  </DialogTitle>
  <QuestionForm
    dimensionId={dimensionId}
    action={dialog.action}
    questionData={dialog.data}
    handleClose={handleClose}
    setQuestions={setQuestions}
    setRows={setRows}
  />
</Dialog>


2
投票

在对话框标签中删除 onClose 事件函数。然后只需在下面添加一个按钮,让我们说“取消”,然后您就可以调用函数来关闭对话框

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

<Dialog
  fullWidth={true}
  open={open}
>
....
 <DialogActions>
    <Button onClick={handleClose} disabled={loading}>Cancel</Button>
 </DialogActions>
</Dialog>

1
投票

只需在组件中添加“disableBackdropClick”属性即可。这将限制(禁用)弹出窗口或对话框的外部点击。

    //Example
    <DialogCss
      style={{ zIndex: 2000 }}
      open={ruleBoxOpen}
      keepMounted
      onClose={() => setRuleBoxOpen(false)}
      aria-labelledby="alert-dialog-slide-title"
      aria-describedby="alert-dialog-slide-description"
      disableBackdropClick
    >

1
投票
如果背景/对话框外部单击,则不执行任何操作/不关闭对话框。确保该过程正确完成
const handleMeetingCreateDialogClose = (event, reason) => {
        if (reason && reason === "backdropClick")   return; 
        setFormData(formInitial);
        setMeetingCreateDialogOpen(false);
};
<Dialog open={meetingCreateDialogOpen} onClose={handleMeetingCreateDialogClose}  disableEscapeKeyDown  >

0
投票

您可以创建一个类似的组件,例如这个:

import React, { ReactNode } from "react";

export function CustomDialog(props: {
  open: boolean;
  children: ReactNode;
}) {
  if (!props.open) return <></>;
  return (
    <div
      style={{
        position: "fixed",
        top: "50%",
        left: "50%",
        transform: "translate(-50%, -50%)",
      }}
    >
      {props.children}
    </div>
  );
}

希望这有帮助!


0
投票

这也是我的问题,似乎没有人很好地回答它。这就是我所做的。

onClose
包装纸上取下
<Dialog >
,即
<Dialog>
的外观如下:

<Dialog
    sx={{
        position: 'absolute',
        left: 300,
        top: 35
    }}
    maxWidth="lg"
    open={open}
    // onClose={handleClose}      <<<<<<<
    ....
>

最后,将

handleClose
函数添加到
onClick
按钮的
close
事件中。

<Button
    color="primary"
    size="large"
    type="submit"
    variant="contained"
    onClick={handleClose}
>
    Close
</Button>

你的问题将会得到解决。


0
投票

这是我删除标志的完整解决方案,因为已取消范围,但保留功能。

这是对话框:

  <Dialog
    open={showModal}
    disableBackdropClick
    disableEscapeKeyDown
    aria-labelledby="alert-dialog-title"
    aria-describedby="alert-dialog-description"
    onClose={handleDlgClose}
  >
    <DialogTitle id="alert-dialog-title">
      The title of the dialog
    </DialogTitle>
    <DialogContent>
      <DialogContentText id="alert-dialog-description">
        The message is here
        {bestScore} moves.
      </DialogContentText>
    </DialogContent>
    <DialogActions>
      <Button onClick={handleOk} color="primary">
        Restart
      </Button>
    </DialogActions>
  </Dialog>
enter code here

拦截关闭事件的函数,如果它来自后台点击并返回而不关闭对话框:

const handleDlgClose = (event, reason) => {
  if (reason && reason == "backdropClick") {
    console.log('backdropClicked. Not closing dialog.')
    return;
  }

  setShowModal(false);
}

然后处理程序并删除属性: ...

https://dev.to/teaganga/handle-dialogdisablebackdropclick-descoped-property-warning-in-mui-v5-2i35

© www.soinside.com 2019 - 2024. All rights reserved.