D Durham
D Durham

Reputation: 1341

Form in Material UI Dialog using React

I am trying to get a form working inside of a Material UI Dialog component. If I wrap the Dialog in the form tags, they do not even show up in the resulting html (no idea why yet)...

<form onSubmit={someFunction}>
  <Dialog>
    ...
  </Dialog>
</form>

If I reverse it and put the form tags inside the Dialog, the form elements show up in the resulting html, but then the action button set to type="submit" will not fire the form's onSubmit.

<Dialog>
  <form onSubmit={someFunction}>
    ...
  </form>
</Dialog>

Has anyone had any success getting this combination to work? I know I can just call the function directly from the action button click, but I am also using Redux Form and have other non-dialog forms in the app, so I have it bound to the form element. So I really need to invoke the form submit from a Dialog somehow.

Upvotes: 5

Views: 11329

Answers (5)

siamhunter jet
siamhunter jet

Reputation: 1

<form onSubmit={someFunction}>
  <Dialog disablePortal>
    <DialogTitle>
      title!
    </DialogTitle>
    <DialogContent>
      form fields go here
    </DialogContent>
    <DialogActions>
        <button type="submit">submit!</button>
    </DialogActions>
  </Dialog>
</form>

Upvotes: 0

Roy Hadad
Roy Hadad

Reputation: 118

The material-ui Dialog component inherits from the material-ui Modal component, which means it accepts the prop "disablePortal" - which is false by default.

from the docs: "Disable the portal behavior. The children stay within it's parent DOM hierarchy." https://material-ui.com/api/modal/#props

by default, the dialog is rendered as a child of your root html node, to have it render inside the <form> tag, you need to disable the portal behavior.

<form onSubmit={someFunction}>
  <Dialog disablePortal>
    <DialogTitle>
      title!
    </DialogTitle>
    <DialogContent>
      form fields go here
    </DialogContent>
    <DialogActions>
        <button type="submit">submit!</button>
    </DialogActions>
  </Dialog>
</form>

Upvotes: 7

D Durham
D Durham

Reputation: 1341

Actually - I have/had the onSubmit={handleSubmit(this.myFunction)} to begin with and that was not the issue. The issue turned out to be how Material UI mounts the Dialog (which apparently is different than react-toolbox). They mount it on the body - I assume for easier positioning - so anything outside of the Dialog is ignored.

With the form inside the Dialog, the buttons are outside the form (which is again apparently different than react-toolbox). So to make it work, you have to use the HTML 5 'form' attribute as detailed here (along with a poly-fill for older browsers if needed). The form needs an id attribute and then the button outside it needs a form attribute with the value set to the id of the form. Then the form elements inside the dialog behave as expected. Thanks for the response though!

Upvotes: 10

JFAP
JFAP

Reputation: 3727

Instead of onSubmit={someFunction}, make it

 <Dialog>
  <form onSubmit={this.someFunction}>
    ...
  </form>
</Dialog>

Upvotes: -3

natac
natac

Reputation: 342

Hey yeah I have this combo working... well I am using the Dialog component from react-toolbox which is very similar to Material-ui but they use Css-modules for styles instead of inline.

So the function you provide to the onSubmit attribute of the form element is going to be the handleSubmit function from redux-form. If you want to do anything such as dispatch actions and store the data then you will need to pass in an onSubmit function to the handleSubmit function. What happens is your onSubmit function is called with the values(object with properties of the values of your form) and the dispatch function from the redux store. You can see the project I have which has the setup you are looking for.

Upvotes: -2

Related Questions