I have a functional component inside which I have a button. I want to call a functional component when that button is clicked.
When we click Submit button the Preview button shows up and when the user clicks the preview button then Preview functional component is called.
const Form =(props)=>{
handlePreview=(e)=>{
e.preventDefault();
return <Preview/>
}
return(
<input name="email" type="text"/>
<button type="submit" onClick={props.handleSubmit}>Submit</button><br/>
{props.render&&
<button type="submit" onClick={handlePreview}>Preview</button>
}
)
}
When I click the Submit button the Preview Button shows up but when I click the Preview Button it doesnt navigate to the <Preview> functional component
To render component you should return it from function Form. If you return any component from event handler it will be ignored.
So to show <Preview/> component you should create local state. In functional components it can be done with React Hooks like below
const Form =(props)=>{
const [isPreviewShown, setPreviewShown] = useState(false);
handlePreview=(e)=>{
e.preventDefault();
setPreviewShown(true); // Here we change state
}
return(
<input name="email" type="text"/>
<button type="submit" onClick={props.handleSubmit}>Submit</button><br/>
{props.render&&
<button type="submit" onClick={handlePreview}>Preview</button>
}
{isPreviewShown && <Preview/>}
)
}
Related
I have react app with with complex component layout with multiple forms.
I know that placing one form inside another is not allowed. But I have a component which renders a form and must be placed inside my form. To prevent forms be rendered one inside another I use react portal.
But when I try to submit form rendered with portal, first form is also submitted that is unexpected. Looks like I miss something important.
How to prevent first form submit when submitting the second?
Thank you
Simplified example is here
import { createPortal } from "react-dom";
const Portal = ({ children, elm }) => createPortal(children, elm);
export default function App() {
return (
<div className="App">
<form
onSubmit={(e) => {
e.preventDefault();
alert("submit 1");
}}
>
First form <input type="text" value="1" />
<Portal elm={document.querySelector("body")}>
Second form{" "}
<form
onSubmit={(e) => {
e.preventDefault();
alert("submit 2");
}}
>
<input type="text" value="2" />
<input type="submit" value="submit 2" />
</form>
</Portal>
</form>
</div>
);
}
I had the same problem, as #EisaRezaei said in the first comment, using e.stopPropagation() in the form inside the portal, and submit type buttons, everything worked fine
I am trying to create a simple form using React using the below code:
<div className="wrapper">
<h1>How About Them Apples</h1>
<form onSubmit={handleSubmit}>
<fieldset>
<label>
<p>Name</p>
<input name="name" />
</label>
</fieldset>
<button type="submit">Submit</button>
</form>
</div>
Now, what I want know is we are not using any inlien function to call the on-submit handler, but it is not being called during render like it would be called if I had done the same for an on-click-handler like:
<button onClick={onClickHandler}>Button</button>
Am I missing something ?
The onSubmit is not working because you didnot create a function.
A function in a simple definition is what you define to do something for you. if you create a function like this:
const onClickHandler =()=>{
console.log('You clicked me')
}
And then you call it in your button like this Button, it will log 'You clicked me to the console' whenever you clicked on that button. This is because you create a function called onClickHandler which will do something for you and i.e log "You clicked me" to the console.
But if you call it like this Button without creating a function that will do something. Then the button will do nothing, it will not work.
To do an inline function on the button so that it will do something for you, you have to do it like this:
<button onClick={()=> console.log('You clicked me')}>Button
And it will work because we define the function directly inside the button instead of defining the function before creating a button.
All this also apply with onSubmit. If you didnot create a function that will do something for you or if you didnot use the function directly by adding ()=> then your onSubmit form will not submit all your input.
Forthe onSubmit to work, you should do something like this:
<form onSubmit={()=> console.log('You submitted your form')}>
//All input goes here
</form>
Note: If what you want to do inside the function is more than, then dont forget to do both inline function and seperate function like this:
for inline
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
()=>{
console.log('abc....')
console.log('abc....')
}
for seperate function
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
const onSubmit()=>{
console.log('abc...')
console.log('abc...')
}
Does this make what you want?
function onClickhandler(event) {
event.preventDefault()
console.log('Submit!')
}
<div className="wrapper">
<h1>How About Them Apples</h1>
<form>
<fieldset>
<label>
<p>Name</p>
<input name="name" />
</label>
</fieldset>
<br />
<button onClick={onClickhandler(event)}> Submit</button>
</form>
</div>
Or you can do the same with type=submit button
function handleSubmit(event) {
event.preventDefault()
console.log('Submit!')
}
<div className="wrapper">
<h1>How About Them Apples</h1>
<form onSubmit={handleSubmit(event)}>
<fieldset>
<label>
<p>Name</p>
<input name="name" />
</label>
</fieldset>
<br />
<button type="submit"> Submit</button>
</form>
</div>
I have an React form.
This form have a button.
This is the submit button.
If i click this button execute the first function (submitHandler)which pointer is on the form.
I want add a second button to the form the "back button".
This button should execute an other function but not the first function
Both button should be on the same form
Form.js
import React, { useState } from "react";
import "./Form.css";
const Form = (props) => {
const submitHandler = (event) => {
event.preventDefault();
console.log('Some console log now from Submit Hanlder')
};
const secondFunction = event =>{
console.log('Some other console log')
}
return (
<form onSubmit={submitHandler}>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input type="text" />
</div>
<div className="new-expense__control">
<label>Amount</label>
<input type="number" />
</div>
<div className="new-expense__control">
<label>Date</label>
<input type="date" />
</div>
<div className="new-expense__actions">
<button type="submit">Submitting</button>
<buton>Second button....</buton>
</div>
</div>
</form>
);
};
export default Form;
just use type="button":
<button type="button">Second button....</button>
You can add a onClick event to the second button to execute the secondFunction:
<button onClick={() => secondFunction()}>Second button....</button>
Note: the onClick event in reactjs is with a Capital letter C.
const secondFunction = event => {
event.preventDefault();
console.log('Some other console log')
}
class Index extends React.Component {
state = {isLoading: false}
onSubmit = (event) => {
console.log('here we go');
event.preventDefault();
// this.checkEmailExistance();
};
render() {
return (
<>
<form id="myForm" onSubmit={this.onSubmit} noValidate>
<CredentialsInputs />
</form>
<footer>
<Button type="submit" form="myForm" isPrimary isDisabled={!isValid}>
Continue
</Button>
</footer>
</>
)}
}
onSubmit function is not invoked
Note: the props (type and form) was passed well and check using the console elements
Is the problem something related to react?
You have written you submit button outside of form. You should move your submit button inside of form,
<form id="myForm" onSubmit={this.onSubmit} noValidate>
<CredentialsInputs />
<footer>
<Button type="submit" form="myForm" isPrimary isDisabled={!isValid}>
Continue
</Button>
</footer>
</form>
If you don't want to move footer inside of form, then you should have onClick on your Button
<form id="myForm" noValidate>
<CredentialsInputs />
</form>
<footer>
<Button type="submit" form="myForm" isPrimary isDisabled={!isValid} onClick={this.onSubmit}>
Continue
</Button>
</footer>
Put the button inside form. it will work.
You should always include a button element inside form to trigger onSubmit method automatic, Else you can call the method manually with onClick event of the button.
You can set a ref to the form, and then in the "Button onClick", you do ref.submit().
In that situation, you set an id to the form... So, if you want to make a really really ugly implementation, you could do something like document.getElementByid('myForm').submit()
If you want to do something better, you should do something like...
<form ref={ref => this.formRef = ref} ...
<button onClick={() => this.formRef.submit()}
Still... not super beautiful. I would recommend Hooks + useRef.
A simplified version of my code. If I click the submit button by itself, the onSubmit handler is called.
If I click submit right after editing the input box, the onSubmit handler won't be called. Is this how React is designed? How to call onSubmit in this case.
const EmailInput = React.createClass({
handleOnBlur(event){
console.log('onBlur')
},
render(){
return <div className="form-group">
<label htmlFor={this.props.name}>Email</label>
<input className="form-control"
type='text'
name={this.props.name}
onBlur={this.handleOnBlur}
value={this.state.val}
/>
</div>
}
})
const Form = React.createClass({
onSubmit(e){
console.log('onSubmit')
},
render(){
return <form onSubmit={this.onSubmit}>{this.props.children}</form>
}
})
ReactDOM.render(<Form>
<EmailInput />
<button type="submit" className="btn btn-primary" >Share</button>
</Form>, mountNode)
Based on Dhaval's answer, I found the reason of this.
When I use Webstorm js debugger, the submit event won't fire. When I just use the browser by itself. It works out fine.
This is so weird that I doubt I'm doing something wrong. Can someone try it on the Webstorm.
Please check the below mentioned Plunkar when I click on Share button it will called onSubmit
// Code goes here
var EmailInput = React.createClass({
handleOnBlur(event){
console.log('onBlur')
},
getInitialState:function()
{
return{
val:''
}
},
render(){
return <div className="form-group">
<label htmlFor={this.props.name}>Email</label>
<input className="form-control"
type='text'
name={this.props.name}
onBlur={this.handleOnBlur}
value={this.state.val}
/>
</div>
}
});
var Form = React.createClass({
onSubmit(e){
console.log('onSubmit')
},
render(){
return <form onSubmit={this.onSubmit}>{this.props.children}</form>
}
});
React.render(<Form><EmailInput /><button type="submit" className="btn btn-primary" >Share</button></Form>,
document.getElementById('example')
);
Demo