Form in Material UI Dialog using React - reactjs

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.

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!

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>

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

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.

Instead of onSubmit={someFunction}, make it
<Dialog>
<form onSubmit={this.someFunction}>
...
</form>
</Dialog>

Related

Text Field Changed Value not updating in OnSubmit - React-Hook-Form & React Js

I am new to React. I am facing an issue while I try to handle a form submit.
Anyone knows this answer please let me know, Using React Material-UI, React-Hook-Form With the controller.
My program has 3 TextFields.
Calculation:
PendingTime=ActualTime-working time;
actual-time is a default value (value is 5). While I change the WorkTime Text field value,
Pending Time automatically updates the pending time value. I added the onChange event in the WorkTime Text field. In the OnSubmit event, I need to get the actual-time value, WorkTimeValue, and PendingTimeValue. But I was not able to get the value onSubmit.
I wrote my code in CodeSandbox.
React-hook-form TextFieldChange value not trigged in onSubmit Event
ScreenShot:
To answer your question, the reason why is not submitting the form is because you're not tying the Button component to the input, add this prop to your component and you'll be able to submit the form
<Button variant="contained" type="submit">Submit</Button>
the type="submit" should allow to submit the form.
Now that you have the answer, you're not using react hook form correctly, you should not mix React.useState with react-hook-form since its loses it purpose, please read the documentation on how to use the register hook with inputs and if you need to update the one of the input values, just watch for the input changes and you'll be read to go.
Also you're getting a warning because you have a form nested inside a form, so instead of using the box as a form change it to be a div or whatever that is valid html nesting:
<Box
component="div"
sx={{
"& > :not(style)": { m: 1, width: "25ch" }
}}
>
Here's a working sandbox with all the functionality you want to do:
Working sandbox
This includes calculating the pending time every-time you change the actualTime and the workTime and it will submit properly, also the useState is removed since you don't need it.
Remove your form tag completely, and place the onSubmit handler inside the Box component.
See, you assigned its component to form, which means you have a nested form inside your form. the submit button is inside the nested form, and onClick does not call the onSubmit function inside the outer form.
Some Material-Ui components accept a component attribute, and it creates an HTML tag of that specified value.
return (
<Box
onSubmit={handleSubmit(onSubmit)}
component="form"
sx={{
"& > :not(style)": { m: 1, width: "25ch" }
}}
noValidate
autoComplete="off"
>
// ...
</Box>
);
CodeSandBox Example

ReactJS, Formik, Bootstrap Modal - Submit from modal button

I have the following structure in my ReactJS App - CodeSandBox link.
I'm trying to somehow submit the Formik form by using a button of Bootstrap modal window, however I am unable to understand how to call the form submission from 2 components down the tree and bring the functions together.
Could someone kindly advise whether it's even something that can be achieved?
Thanks!
In the FormFields component, you need to add an id to your form
<Form id="fooId">
and for the modal button you add the form and type attribute like:
<Button
...
type="submit"
form="fooId"
...
/>
And the form would be submitted. You can skip passing the onClick event to that button and pass the doSubmit method to the Formik component in FormFields component.
Codesandbox

Pass Accessibility Props to Material UI Button

I want to add accessibility features to the Material UI Button.
I expect to use this custom button as follows:
import Button from '#material-ui/core/Button';
function AccessibleButton(props) {
const { accessKey, ariaLabel, isDisabled, label, onClick, tabIndex, variant, size} = props;
return (
<Button
accesskey={accessKey}
aria-label={ariaLabel}
disabled={isDisabled}
className={componentCls}
onClick={onClick}
tabindex={tabIndex}
variant={variant}
size={size}
>
{label}
</Button>
);
};
Aria labels are available for inputs, but don't seem to be for buttons. How do I pass the additional props (accessKey, ariaLabel) into the Material UI Button. How do I do this?
This should work since most of our components forward their excess props. On the corresponding api pages (here https://material-ui.com/api/button/) you will find a table with the apparent props. Below that is a note that tells you what happens with excess props.
It's a bit iffy to navigate (we're working on it) but in the end you'll see that excess props are forwarded to the native element. So <Button aria-label="ariaLabel" /> will render a <button aria-label="ariaLabel" />.
Your code should work.
I have created sandbox where you can inspect the button and see the button will have aria-label and accesskey attribute.
<Button
aria-label="This is aria label"
accessKey="Key"
variant="contained"
color="primary"
>
I'm a button
</Button>
Try inspecting button in below sandbox.

React Semantic-UI: Modal component with Form component? Is it possible?

So, I'm trying to use Semantic UI modal component with the form component.
My problem is that if I use these two together the UI becomes bad.
I created a sandbox about my current situation: https://codesandbox.io/s/2n1pj96ry
As you can see now the submit button does not attached to the form.
If I move the Form component directly inside the Modal component, like this:
<Modal...>
<Form>
...
</Form>
</Modal>
the submit will attached to the form, but the UI breakes down.
I tried to add different classes to these components (like ui modal to the Form component, but it doesnt worked well).
Do you have any suggetsion?
Thanks for you help!
You can use the as prop on the Modal to make it a form element.
<Modal
as={Form}
onSubmit={e => handleSubmit(e)}
open={true}
size="tiny">
Any button with the submit type in your modal will fire the onSubmit handler. I find this to be a nice way to opt-in to required fields and easy validation by the browser on form elements.
Be sure to pass the event to your submit handler and use the preventDefault method to avoid the browser from automatically trying to post your form.
Forked your sandbox and made a working example. The modal is changed to a <form> element, the Input has the required property and the browser will demand the element is valid before firing the onSubmit handler. The default form action is prevented, and you can handle as desired with whatever.

React does not recognize the `anyTouched` prop on a DOM element

i have redux form inside my reactstrap modal.when my popup appear,console log show below warning.without Form it's working charm.
You have a component say it's name is CustomComponent that retuns something like this
<div>
<Form {...this.props}>
<p> this.props.pText </p>
<Button>I'm a button named {this.props.buttonName} </Button>
</Form>
</div>
and when you render it in another file you do this
<CustomComponent pText="hi" buttonName="randomName">
so what happens is you are passing the buttomName, pText to your Form which doesn't accept pText, buttonName (remember, Your button & accept those props but not the form itself, so the virtual react DOM guesses that the prop is not for react, so it must be a real DOM prop & doesn't know what to do with it, to solve the problem, simply remove the {...this.props}
this is a result of how React is handling custom vs predefined DOM attributes -> see here
https://reactjs.org/warnings/unknown-prop.html

Resources