I have issue with my final form. I have a Modal with a react-final-form in it and would like to submit the form with the button which is in the footer of the modal. Submit button has onSubmit event, when I clicked this button I saw that my onSubmit function doesn't work. It works when I click button which opens modal.... What is going wrong here?
Advert.js
class Advert extends React.Component {
showLoginMenu = (e) => {
e.preventDefault();
this.props.loadModal(LOGIN_MODAL);
};
....
<button onClick={this.showLoginMenu.bind(this)}>Order</button>
}
Modal.js
<Modal onClose={this.onClose.bind(this)}>
<Form
onSubmit={this.onSubmit}
initialValues={initValues}
decorators={[calculator]}
render={({handleSubmit}) => (
<form onSubmit={handleSubmit}>
<some fields>
<button type="submit" onSubmit=
{this.onSubmit}>Order</button>
</form>
)}
/>
As far as I know, onSubmit is a prop of form tag, not button tag. You should use onClick instead.
I know this has probably been resolved by now as this issue is about 2 years old.
But to resolve this issue you need to include the Modal inside of the Form component, but before the form tag
<Form
onSubmit={this.onSubmit}
initialValues={initValues}
decorators={[calculator]}
render={({handleSubmit}) => (
<Modal onClose={this.onClose.bind(this)}>
<form onSubmit={handleSubmit}>
<button type="submit" onSubmit={this.onSubmit}>Order</button>
</form>
<Modal>
)}
/>
Related
I have a common modal with a footer submit button. The modal is able to accept children.
const Modal = ({ children }: PropsWithChildren<Props>) => {
return (
<div>
{children}
<div>
<button type="submit">submit</button>
</div>
</div>
)
}
export default Modal
Usage
const CreateModal = (props: Props) => {
return (
<Modal>
<form>
<input name="test" />
</form>
</Modal>
)
}
export default CreateModal
Currently, that are a lot of files using the Modal component and I don't want to move the form tag in the modal.
My question is how can I modify the children in the common modal component? I want to append a hidden input inside the form so that I can submit the form when press Enter.
Wonder if using react cloneElement is able to solve my problem as I know it only can pass additional props to it.
I am using react hook form btw.
This is how I solve it.
<ModalBody display="flex" flexDirection="column">
<form onSubmit={onSubmit}>
{children}
<input hidden type="submit" />
</form>
</ModalBody>
I still need to edit all files but for future usage, I no need to include a hidden input for all files.
The only thing I worry is the FormProvider now is nested inside the form. By default the <FormProvider> should be the parent of the <form>.
I'm getting trouble to understand the following situation in ReactJS.
I have a conditional rendering between two buttons: a button which shows another, basically. The second button is a submit type, and both buttons are inside the form. When I click at the first button to show/render the second one, in my understanding, it should just show the second button, and not submit the form automatically.
I reproduced the case with the create react app:
function App() {
const [showSubmit, setShowSubmit] = useState(false);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<form method="POST" action="#">
{showSubmit ? (<button type="submit">Send</button>)
:
(<button type="button" onClick={() => setShowSubmit(true)}>
Show Submit
</button>)}
</form>
</header>
</div>
);
}
Why does the ReactJS automatically fires the submit event if I just want to show/render the submit button?
Posting here for anyone in the future who encounters this issue (probably me) - the issue you've described can be remedied by adding a key prop to the button elements, to let react distinguish between the button elements you're replacing.
Handle the form onSubmit function prevent the default function call, when ever you try to click on any button inside the form it will try to submit the form so use the e.preventDefault() to prevent it from submitting.
You can try handling the submission yourself using the onSubmit on the form tag instead of letting the browser do it for you.
import React, { useState } from 'react';
import './style.css';
function App() {
const [showSubmit, setShowSubmit] = useState(false);
console.log('state', showSubmit);
return (
<div className="App">
<header className="App-header">
<img src={'logo'} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<form method="POST" action="#" onSubmit={(e) => e.preventDefault()}>
{showSubmit ? (
<button type="submit">Send</button>
) : (
<button type="button" onClick={(e) => setShowSubmit(true)}>
Show Submit
</button>
)}
</form>
</header>
</div>
);
}
export default App;
I was trying to make a simple react weather app and it worked but not properly because before add the material-ui button it was working perfect and now it is working only if i click enter not click on the button because the material-ui const city = e.target.elements.city.value; this code is not working with it at all
here is the form component is like
return (
<div>
<form onSubmit={props.getWeather}>
<p>Just type the city name </p>
<p className="check">you must spelling correctly</p>
<TextField
id="standard-basic"
name="city"
placeholder="City....."
variant="outlined"
/>
<Button onClick={props.getWeather} variant="contained" color="primary">
find
</Button>
</form>
</div>
);
};
export default Form;
and in the app component
getWeather = async e => {
e.preventDefault();
const city = e.target.elements.city.value;
const api = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${API_KEY}`
);
const data = await api.json();
Remove onClick handler from button and add type="submit", so it'll work both in case of Enter click and button click:
<Button type="submit" variant="contained" color="primary">
find
</Button>
It's going to work only when your button is in hierarchy of <form> type="submit" simply submits the form.
Seems I can't get a grip on how React-final-form works.
There is a functional component with the following sections:
At the top:
import {Form, Field} from "react-final-form";
Then in the return:
return (
<Fragment>
<Form
onSubmit={handleSubmit}
render={ ({innerSubmit, form, submitting, pristine, values}) => (
<form onSubmit={innerSubmit}>
( Bunch of Fields... )
<div className="buttons">
<button type="submit" disabled={submitting}>
Save
</button>
<button
type="button"
onClick={form.reset}
disabled={submitting || pristine}>
Reset
</button>
</div>
</form>
)}
/>
</Fragment>
)
So, the render is a function which passes an object. In that object, the first one is 'innerSubmit'.
How is innerSubmit connected to the 'handleSubmit'?
And what are these values in the object (innerSubmit, form, submitting, pristine and values). The render function in React.dom (where render is coming from) has different parameters.
Please check documentation carefully. It seems that handleSumbit is kind of author's naming convention and should be used as a prop in render. On the other hand yours 'innerSumbit' (I suppose it's a form-handling function?) should be passed to 'onSumbit' in Form.
Probably a good idea for you is to check react-final-form author's yt tutorial.
I have a search form with a few inputs the user can enter data into and some buttons on the right hand side that toggle the search. Underneath everything is the main 'search' button. What happens when the user hits return or enter in any of the inputs is on of my toggle buttons onClick handlers always fires and I don't know why. I recreated the gist of this in fiddle/code here:
class Sample extends React.Component {
handleSubmit(e) {
e.preventDefault();
console.log('handle search called');
}
handleClick(e) {
e.preventDefault();
console.log('handleClick called');
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div className="filterRow">
<div className="filterColumn1">
<label style={{"display":"block"}}>
Name:
<input type="text" name="name" />
</label>
<label>
Id:
<input type="text" name="id" />
</label>
</div>
<div className="filterColumn2">
<button key="sth" onClick={this.handleClick}>
do something
</button>
</div>
</div>
<button type="submit" onClick={this.handleSubmit}>
SEARCH
</button>
</form>
);
}
}
ReactDOM.render(<Sample/>, document.getElementById('app'))
JSFiddle
Question: Why does the click handler on that button fire when you hit enter or return in the inputs? How come its not the handleSubmit which is the onsubmit of the form?
When you hit Enter this triggers your button with submit type (that's just natural behavior of forms not sure why). Your button onClick handler (handleClick) has e.preventDefault() called which prevents further bubbling of an event and that's why handleSubmit is not getting triggered.
If you change button type to type="button" then Enter will not trigger your button onClick handler.
Btw. on your example onSubmit has handleSearch as event handler but I guess you meant handleSubmit.