React Forms and Events - reactjs

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.

Related

Issue with submitting the form when the button in search bar is clicked in react

I am having issue with when a user inputs a value in the search bar and click the button it either throws an error in the console (Uncaught (in promise) SyntaxError: Unexpected token U in JSON at position 0) and the value passed to the handleSubmit is undefined. However, I am able to pass the value when I hit the enter button as keyPress function please let me know what I am doing wrong and thank you in advance!
SearchBar.js
const Navbar = ({ searchBarText, setSearchBarText }) => {
function handleSubmit(e){
console.log('submitted Value', e.target.value);
setSearchBarText(e.target.value)
e.preventDefault();
}
function keyPress(e){
if(e.keyCode === 13 || e.key === 'Enter' ){
console.log('value', e.target.value);
setSearchBarText(e.target.value)
// put the login here
e.preventDefault();
}
}
return (
<>
<nav className="navbar navbar-expand-lg navbar-light bg-light ">
<form onSubmit={handleSubmit}>
<div className="search-container" >
<span className="search-icon-btn">
<button className="search-icon-btn" type="submit" onClick={handleSubmit} >
<i className="fa fa-search" value={searchBarText}></i>
</button>
</span>
<div className="search-input">
<input
type="text"
className="search-bar"
placeholder="Search...."
onKeyDown={keyPress}
/>
</div>
</div>
</form>
</nav>
</>
);
}
export default Navbar;
When I click the highlighted button the data in console shows undefined.
The event passed to handleSubmit is the click event on the button, so e.target.value is the value of the button, which is presumably undefined.
The quickest fix is to give the input an Id and select its value to pass to setSearchBarText:
const searchInput = document.getElementById("searchInput");
setSearchBarText(searchInput.value);
A "better" fix is to use state. Bind a handler to the input's onChange or onInput that updates a state value. Then you can bind a single submit handler to both the button's onClick and the input's onKeyDown that retrieves the state value and passes it to setSearchBarText()

Get value from textarea input in event object

I have a form with a textarea where users can put comments, and then trigger a onClick (when the form is submitet via the button).However, I cant get the value of the input, for example if a user writes "test", I want it to get into the handleSubmit function.
My form
<form onSubmit={this.handleSubmit.bind(this)} method="POST">
<label>Skicka</label>
<textarea placeholder="Type in comments (allergis etc.)" name ="name" ref ="name"></textarea>
<button className="btn" type="submit">
Send
</button>
</form>
//my handler
public handleSubmit = event => {
event.preventDefault();
console.log(event.name.value)
}
You have to save the textarea value separately in the onChange method of the textarea like this (for class component):
<form onSubmit={this.handleSubmit.bind(this)}
method="POST"
>
<label>Skicka</label>
<textarea
onChange={this.setComments}
placeholder="Type in comments (allergis etc.)"
name="name"
value={this.state.comment}/>
<button className="btn" type="submit">
Send
</button>
</form>
// The save function
const setComments = e => this.setState({comment: e.target.value});
This will save the textarea input in your local state and you can access it in your submit function with this.state.comment.
Hope this helps. Happy coding.
As you are using Uncontrolled Component. You can make use of ref to get value.
handleSubmit = (event) => {
event.preventDefault();
console.log(this.refs.name.value)
}
Demo
Note: In React you should never add method="POST" and action attribute's on form.
Don't add public keyword to your function (if you are not using typescript).
Better approach to work with form values, is Controlled Component
You can fix it by changing the handleSubmit method. Check below updated method.
public handleSubmit = event => {
event.preventDefault();
console.log(event.target.name.value)
}
But if you are work with React application then update the state variable via onChange event.

How to prevent enter key triggering submit

I am using Formik for a little form in a React app.
The method handleSubmit is triggered when user hits the enter key.
Is there a way to prevent that triggering?
I didn't find anything in the formik docs...
Thanks.
You could add an onKeyDown handler like this:
/**
* Stop enter submitting the form.
* #param keyEvent Event triggered when the user presses a key.
*/
function onKeyDown(keyEvent) {
if ((keyEvent.charCode || keyEvent.keyCode) === 13) {
keyEvent.preventDefault();
}
}
/**
* Sample form component.
*/
function Example() {
return (
<Formik initialValues={{ name: "" }} onSubmit={() => console.log("Submit")}>
<Form onKeyDown={onKeyDown}>
<div>
<label htmlFor="name">Name</label>
<Field id="name" name="name" type="text" />
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
);
}
See CodeSandbox example here.

Submit Final Form from modal

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>
)}
/>

How to force Enter key to trigger "submit" function without need to focus an input

I'm making an app in react-redux and I want a simple feature but that's starting to look tricky to implement.
:)
I want to be able to open my webapp (I land on my login screen) and just hit enter (the browser has already saved my user and password and they are filled in in the correct input fields) and have that "enter" keystroke tigger my login function without me needing to click anywhere first to focus something.
(On a non-root component)
I've already got my password input (the last one) bound to the enter key correctly.
So pressing enter when I have the password field focused works :
handleSubmit() {
const { authenticate } = this.props;
const { tusername, tpassword } = this.state;
const credentials = {
username: tusername,
password: tpassword,
};
authenticate(credentials);
}
_handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
}
};
render() {
return (
<div onKeyPress={this._handleKeyPress} >
<Card id="signin">
<CardImg top width="100%" src={rubisLogo} alt="Rubis" />
<InputGroup>
<Input
placeholder="Nom d'utilisateur"
value={this.state.tusername}
onChange={this.updateUser}
/>
</InputGroup>
<InputGroup>
<Input
placeholder="Mot de passe"
type="password"
value={this.state.tpassword}
onChange={this.updatePassword}
onKeyPress={this._handleKeyPress}
/>
</InputGroup>
<div>
<Button
id="btn"
onClick={this.handleSubmit}
to="/home">Login
</Button>
</div>
<ModalPassword class="modal" buttonLabel="Mot de passe oublié ?" />
<ModalAccount class="modal" buttonLabel="Créer un compte" />
</Card>
</div>);
}
as you can see I've tried putting it on the div but that didn't work. also I don't want a solution based on that. I want the enter-key to be a gobal fallback on this view. the user can't loose this funtionality just because he clicked somewhere.
Set the focus to the div by default using tabIndex so that the javascript event will be triggered
render() {
return (
<div onKeyPress={this._handleKeyPress} tabIndex="1" >
<Card id="signin">
..)}
You have to wrap your components with a form tag instead of a div, handle the onSubmit event, and the property type of Login button you must set it to submit.
...
handleSubmit = (e) => {
e.preventDefault(); // prevent browser behavior
// Handle submit logic
...
};
render() {
return (
<form onSubmit={handleSubmit}>
...
<Button
id="btn"
type="submit"
to="/home">Login
</Button>
</form>
);
}

Resources