What is the easiest way to show a confirmation dialog in react-admin?
Asked Answered
E

4

10

In a react-admin project I created my own toolbar button that should display a confirmation dialog, similar to the JavaScript alert but not quite as ugly.

Only when the user clicks OK, things should happen, in my case some database operations.

is there an ootb alert dialog in react-admin or what is an easy way to create one? I could not find anything in the docs about that topic. I tried the alert example from material ui (see https://v1.material-ui.com/demos/dialogs/) but due to my very limited understandig of react I am not able to create a reusable component from the example.

Update:
The code snippet below illustrates what I'd like to do:

// Definition of a toolbar button
const ActionButton = ({ handleSubmitWithRedirect, ...props }) => {
    const form = useForm();
    var formdata = form.getState().values;

    switch (formdata.status.id) {
        case 0:
            props.label = "Text for state 0";
            break;
        case 1:
            props.label = "Text for state 2";
            break;
        default:
            props.label = "Unknown state"
    }

    const handleClick = useCallback(() => {
        switch (formdata.status.id) {
            case 0:
                form.change('status', status[1]);
                break;
            case 1:
                // Here I want to open a confirmation Dialog...
                if( openAlertDialog("Warning, things will happen","Okay","Better not")) 
                {
                    form.change('status', status[2]);
                    createDatabaseRecord(formdata).then(() => (
                        // success handling [...]
                    ),
                    () => (
                        // error handling [...]
                    ))
                };
                break;
            default:
        }
        handleSubmitWithRedirect('list');
    }, [formdata, form]);
    return <SaveButton {...props} handleSubmitWithRedirect={handleClick} />;
};
Eun answered 20/2, 2020 at 14:15 Comment(1)
if you are looking for a modal like like in bootstrap try use this react-bootstrap.github.io/components/alertsSlob
E
3

There is actually a Confirm component which can be used in a toolbar button like this:

const ExampleButton = ({ handleSubmitWithRedirect, handleSubmit, ...props }) => {
    const form = useForm();
    const notify = useNotify();
    const [open, setOpen] = React.useState(false);
    const handleClick = () => setOpen(true);
    const handleDialogClose = () => setOpen(false);

    const handleConfirm = () => {
        doStuff();
        notify('Stuff is done.');
        handleSubmit();
        setOpen(false);
    };

    var ct = "Do you really want to do stuff?";
    return (<><SaveButton {...props} handleSubmitWithRedirect={handleClick} handleSubmit={handleClick} variant="outlined" />
        <Confirm
            isOpen={open}
            title="do stuff"
            content={ct}
            onConfirm={handleConfirm}
            onClose={handleDialogClose}
            confirm="Yep"
            cancel="Nope"
        />
    </>);
}
Eun answered 12/1, 2021 at 12:7 Comment(1)
From where are you importing the Confirm component? I do not see it in React 18.Aldus
C
1

Check out the following codesandbox for an example on how to trigger opening a dialog using Material-UI as well as triggering different actions based on whether you click the "Agree" or "Disagree" buttons.

https://codesandbox.io/s/material-demo-cspqy

Cella answered 20/2, 2020 at 17:43 Comment(2)
thanks, looks great! I added a code snippet to illustrate what I'd like to do. Unfortunately I am not able to rewrite your example to fit my needsEun
Still have no solution, I use javascript window.confirm() but it is ugly...Eun
A
0

In case it interests anyone, this is the OK/Cancel Dialog I made. It was too hard to close the dialog within the component. I had to have that logic outside the component, but I couldnt find any other way of achieving the closing logic.

//Test.tsx
function Test() {
    const [open, setOpen] = React.useState(false);
    const handleOpen = () => setOpen(true);
    const handleClose = () => setOpen(false);
    return (
        <>
            <Button onClick={handleOpen}> Delete Category</Button>
            {open && <OKCancelDialog open={true} title={"Delete Thing!"}
                                     content={"Are you sure you want to delete thing?"}
                                     handleOK={() => {
                                         handleClose();
                                         alert("yeah")
                                     }}
                                     handleCancel={() => {
                                         handleClose();
                                         alert("cancel")
                                     }}/>}
        </>
    )
}

//OKCancelComponent.tsx
type Props = {
    title: string,
    content: string,
    handleOK: () => any,
    open: boolean
    handleCancel: () => any
}

export default function OKCancelDialog(props: Props) {
    return (
        <Dialog
            open={props.open}
            onClose={props.handleCancel}
            aria-labelledby="alert-dialog-title"
            aria-describedby="alert-dialog-description"
        >
            <DialogTitle id="alert-dialog-title">
                {props.title}
            </DialogTitle>
            <DialogContent>
                <DialogContentText id="alert-dialog-description">
                    {props.content}
                </DialogContentText>
            </DialogContent>
            <DialogActions>
                <Button onClick={props.handleOK}>
                    OK
                </Button>
                <Button startIcon={<CancelIcon/>} onClick={props.handleCancel}>Cancel</Button>
            </DialogActions>
        </Dialog>
    );
}
Alvertaalves answered 9/1, 2022 at 2:33 Comment(0)
R
0

In my case I made a new component "ButtonConfirm".

import React from 'react';

class ButtonConfirm extends React.Component
 {
    constructor(props)
    {
        super(props)

        this.state = {
            title: this.props.title,
            classButtonName: 'buttonForm buttonAlert',
            classDialogName: 'dialog_alert',
            query: this.props.query,
            param: "del",
            param_id: "-1",
            view: "button"
        }
        
    }

    showDialog()
    {
        this.setState({
            view: "query"
        });
        
    }

    onClickYes()
    {
        this.setState({
            view: "button"
        }); 

        this.props.onConfirm("yes",this.state.param, this.state.param_id);
    }

    onClickNo()
    {
        this.setState({
            view: "button"
        });

        this.props.onConfirm("no",this.state.param, this.state.param_id);
    }

    render()
    {
        if(this.state.view == "button")
        {
            return (
                <div className={this.state.classButtonName} onClick={this.showDialog.bind(this) }>{this.state.title}</div>
            );
        }

        if(this.state.view == "query")
        {
            return (
                <div className={this.state.classDialogName}>
                    <div>{this.state.title}</div>
                    <div className='container'>
                        <div>{this.state.query}</div>
                        <div className={this.state.classButtonName} onClick={this.onClickYes.bind(this) } >YES</div>
                        <div className={this.state.classButtonName} onClick={this.onClickNo.bind(this) } >NO</div>
                    </div>
                </div>
            );
        }
    }
 }

 export default ButtonConfirm;    

Then in my "top" component I created new method

 onConfirmDel(type, param, id)
        {
           console.log(type + param + id);
        }

And in render method:

<ButtonConfirm  onConfirm={this.onConfirmDel.bind(this) }  title="Delete" query="Are you sure...?"  />

If you want to use that, you will need css style :)

Refinery answered 11/8, 2022 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.