Form is not submitting from an outer button using react - javascript

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.

Related

Two forms on the same level are submitted in react app

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

Why is onSubmit function not called during render even if we don't use an inline function to call it but onCLick functions are called during render?

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>

Form onSubmit={handleSubmit} is triggered through any button which has type="submit" or not specified or after enter on textbox

I'm trying to get submitter/caller of <form onClick={handleSubmit} />
In event arg I would like to check 'id' of caller button e.g. <button id="submitter">Submit with id</button> and allow continue only if 'id' match.
I have tried Formik, Final-Form, Redux form and also standalone <form> tag.
Even pressing enter on input tag will trigger submit form. I understand that this is default behavior but I need to restrict which caller is allow to continue.
I have to use tag <form> otherwise something like scroll to closest error doesn't work. Tried with Final Forms.
In my application I have lot of bottons for adding fields to array removing and not all of them has type="button" which will prevent this. But as I said even enter on textbox will trigger this onSubmit so I have to find better solution.
Keep in mind that I can't avoid using <form> tag.
Thanks
https://codesandbox.io/s/dazzling-jackson-2m4r5
<form
onSubmit={e => {
e.persist();
e.preventDefault();
// HOW TO GET id="my-submit-button" HERE ???
console.log(e);
if(id==='my-submit-button') handleSubmit()
}}
>
<input type="text" name="firstName" />
<button>Button without type</button>
<button type="button">Button type=button</button>
<button type="submit">Button type=submit</button>
<button id="my-submit-button">Button with id</button>
</form>
As #epascarello mentioned this works -> document.activeElement
You can use event on click:
<form onSubmit={e => e.preventDefault()}>
<input type="text" name="firstName" />
<button>Button without type</button>
<button type="button">Button type=button</button>
<button type="submit">Button type=submit</button>
<button id="my-submit-button" onClick={() => {
console.log("Button click");
// handleSubmit()
}}>Button with id</button>
</form>

React onSubmit handler on a form won't be called if I have a onBlur handler on an input? (Only happens when using Webstorm js debugger)

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

Accessing HTML form elements with same name from javascript

I am using the following solution (How to best implement Save | Save and Close | Cancel form actions in ASP.NET MVC 3 RC) of multiple submit buttons to allow cancel and save from my MVC form:
<form action="Xxxx" method="post" onsubmit="return validatePost()">
...
<input type="submit" name="actionType" value="Save" />
<input type="submit" name="actionType" value="Cancel" />
</form>
With javascript called onsubmit:
function validatePost() {
if(Blah blah){
return true;
}
}
I only want to do this javascript validation if 'Save' is clicked, but cannot tell which button was clicked from the javascript.
I tried getting the actionType value using document.forms[0].elements["actionType"].value but could not, as there is more than one item named actionType on the form.
Can anyone help?
Thanks
You can use id (http://jsfiddle.net/7p5N5/)
<form method="post">
<input id="save" type="submit" name="actionType" value="Save" />
<input type="submit" name="actionType" value="Cancel" />
</form>
function validate() {
alert('Validate');
return false; // cancel click, true will submit
}
$("#save").click(function () {
return validate();
});
If you don't want to use id, you can use $('input[name="actionType"][value="Save"]') to select the Save button
Are you able to listen to the onclick event of only the 'Save' input and have it use your validatePost function.
Then you could have a different function for the onclick of 'Cancel' to do appropriate action.

Categories

Resources