Source:  Twitter logo

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} />;
};

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"
        />
    </>);
}
4 users liked answer #0dislike answer #04
elsni profile pic
elsni

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

1 users liked answer #1dislike answer #11
Kendra Loves Code profile pic
Kendra Loves Code

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>
    );
}
0 users liked answer #2dislike answer #20
Oliver Watkins profile pic
Oliver Watkins

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 :)

0 users liked answer #3dislike answer #30
Blazej Kita profile pic
Blazej Kita

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).