React bind custom handler onChange to input - reactjs

This is my SearchForm.js, it creates form with two inputs keywords and city and select list date
import React from 'react';
import ReactDOM from 'react-dom';
class SearchForm extends React.Component {
constructor(props) {
super(props)
this.state = {
keywords: '',
city: '',
date: ''
}
//this.handleChange = this.handleChange.bind(this)
//this.handleSubmit = this.handleSubmit.bind(this)
this.handleKeywordsChange = this.handleInputChange.bind(this);
}
handleKeywordsChange(event) {
console.log(1);
}
render() {
return (
<form className='form search-form' onSubmit={this.handleSubmit}>
<div class="form-row">
<div class="form-group col-md-5">
<label for="keywords">Keywords</label>
<input type="text" class="form-control" name="keywords" id="keywords" placeholder="Keywords" onChange={this.handleKeywordsChange} value={this.state.name} />
</div>
<div class="form-group col-md-5">
<label for="city">City</label>
<input type="text" class="form-control" name="city" id="city" placeholder="City" onChange={this.handleChange} value={this.state.name} />
</div>
<div class="form-group col-md-2">
<label for="date">Date</label>
<select class="form-control" name="date" id="date" onChange={this.handleChange} value={this.state.value}>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<input id='formButton' className='btn btn-primary' type='submit' placeholder='Send' />
</div>
</div>
</form>
)
}
}
export { SearchForm }
and I need to add different handle function to inputs like handleKeywordsChange, but there are some errors
What's wrong with my bind ?

I think there is a typo in
this.handleKeywordsChange = this.handleInputChange.bind(this);
Have you tried change it to
this.handleKeywordsChange = this.handleKeywordsChange.bind(this);

Error is because of this:
this.handleKeywordsChange = this.handleInputChange.bind(this);
You need to define handleInputChange, instead of handleKeywordsChange:
handleInputChange () {
}
Reason is as per MDN Doc:
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
So in handleKeywordsChange method you are just storing the reference of function returned by bind. So the actual function will be handleInputChange and that you need to define.

Related

function keyword in class based component and inChange event

Can anyone please help me understand if there's any issue with the below code snippet:
import React, { Component } from "react";
class AddContactForm extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
number: ""
}
}
handleOnChange(event) {
console.log("Hi");
console.log(event.target.id);
console.log(event.target.value);
}
render() {
return (
<React.Fragment>
<div className="mx-auto">
<div class="mb-3 row">
<label for="username" class="col-sm-2 col-form-label">Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="username" onChange={this.handleOnChange.bind(this)}/>
</div>
</div>
<div class="mb-3 row">
<label for="mobileNumber" class="col-sm-2 col-form-label">Mobile Number</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="mobileNumber" onChange={this.handleOnChange}/>
</div>
</div>
<div class="mb-3 row">
<label for="emailId" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="emailId" onChange={this.handleOnChange}/>
</div>
</div>
<button className="btn btn-primary w-25">Add</button>
</div>
</React.Fragment>
)
}
}
export default AddContactForm;
I am facing the problems below:
1 - unable to use function keyword with handleOnChange method
2 - none of my inputs are firing the onChange event. I am unable to get any logs in the console as added in HandleOnChange method.
Thanks.
In your constructor bind all the methods.
constructor() {
super();
this.state = {
name: "",
email: "",
number: ""
}
this.handleOnChange: this.handleOnChange.bind(this)
}
And in your inputs use like this
<input onClick={this.handleOnChange} />
You have few errors in your code aside from the one #Muhammad pointed out, some attribute names were altered in to avoid conflict for jsx so:
class became className
for became htmlFor with the label element a similar problem here.
It's also worth noting that, using arrow function is favored over using bind, so you create the function normally as an arrow function.
handleOnChange = (event) => {
console.log("Hi");
console.log(event.target.id);
console.log(event.target.value);
};
and make onChange call it.
onChange={this.handleOnChange}
You can refer for this codesandbox for a demo, you may also want to read these two questions here:
correct-use-of-arrow-functions-in-react
how-to-avoid-bind-or-inline-arrow-functions-inside-render-method

React input box no longer works

I am new to react and when I change my state from just variables to an object the input box no longer works.
The following code works
class AddMovie extends Component {
state = {
title: "",
watched: ""
}
onChangeMovie = (e) => {
this.setState({[e.target.name] : e.target.value});
}
uploadMovie = (e) => {
e.preventDefault();
this.props.addMovie(this.state.title, this.state.watched);
this.setState({title: "", watched: ""})
}
render(){
return (
<form onSubmit={this.uploadMovie}>
<div className="form-group">
<label>Movie Title</label>
<input type="text" className="form-control" placeholder="Enter title"
name="title" value={this.state.title} onChange={this.onChangeMovie}/>
</div>
<div className="form-group">
<label>Date Watched</label>
<input type="date" className="form-control"
name="watched" value={this.state.watched} onChange={this.onChangeMovie}/>
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
)
}
}
export default AddMovie;
When I change the state to an object
state ={
movieUpload: {
title: "",
watched: ""
}
}
and I change the form to add the object
render(){
return (
<form onSubmit={this.uploadMovie}>
<div className="form-group">
<label>Movie Title</label>
<input type="text" className="form-control" placeholder="Enter title"
name="title" value={this.state.movieUpload.title} onChange={this.onChangeMovie}/>
</div>
<div className="form-group">
<label>Date Watched</label>
<input type="date" className="form-control"
name="watched" value={this.state.movieUpload.watched} onChange={this.onChangeMovie}/>
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
)
}
The input box no longer works. Why is this and how do I change it?
If you're going to make those changes, you need to change your onChangeMovie as well
onChangeMovie = (e) => {
this.setState({uploadMovie: {...this.state.uploadMovie, [e.target.name] : e.target.value}});
}
This will copy the current this.state.uploadMovie and then overwrite the title/watched.

Unable to add data from form to variable using REACT

We're trying to set up a data entry form that adds input to an object in mongo. We're positive this has to do with our front end as we can't get the input data to even print to an alert.
import { Panel, Button,ButtonToolbar} from 'react-bootstrap';
export default class ResearcherPortal extends React.Component {
constructor(props){
super(props);
this.state = {
schoolName: '',
studyName: '',
studyDescription: '',
identifier: '',
numberOfConsenting: null,
numberOfNonconsenting: null
},
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event){
this.setState({numberOfConsenting: event.target.value});
alert(this.state.numberOfConsenting);
}
render() {
return (
<div className="jumbotron">
<div className="container ">
<div className ="row justify-content-md-center">
<Panel bsStyle="primary">
<Panel.Heading>
<h2>Researcher Portal</h2>
</Panel.Heading>
<Panel.Body>
<form id="Account Creation" action={"/researcherPortal"} method="POST">
<div className="form-group">
<input type="text" className="form-control" id="schoolName" placeholder="School Name"/>
</div>
<div className="form-group">
<input type="text" className="form-control" id="studyName" placeholder="Study Name"/>
</div>
<div className="form-group">
<input type="text" className="form-control" id="studyDescription" placeholder="Study Description"/>
</div>
<div className="form-group">
<input type="text" className="form-control" id="identifier" placeholder="Unique Identifier"/>
</div>
<div className="form-group">
<input type="text" className="form-control" id="numberOfConsenting" placeholder="Number of Consenting Students" value={this.state.numberOfConsenting}/>
</div>
<div className="form-group">
<input type="text" className="form-control" id="numberOfNonconsenting" placeholder="Number of Nonconsenting Students"/>
</div>
<Button type="submit" className="btn btn-primary" onClick={this.handleSubmit.bind(this)}>Create Accounts</Button>
</form>
</Panel.Body>
</Panel>
</div>
</div>
</div>
);
}
}
Expected result is the input for "Number of Consenting Students", however we are just outputting the initial constructor value.
You need to provide an onChange to the input whose value is this.state.numberOfConsenting. Something like -
changeNumberOfConsenting(event) {
this.setState({ numberOfConsenting: event.target.value });
}
...
<input ... value={this.state.numberOfConsenting} onChange={this.changeNumberOfConsenting} />
and then bind it in your constructor like you did for handleSubmit.
Use refs.
Add handler to constructor:
this.consentingStudents = React.createRef();
Add this ref for needed input:
<input type="text" className="form-control" id="numberOfConsenting" placeholder="Number of Consenting Students" ref={this.consentingStudents} value={this.state.numberOfConsenting} />
And get its value in the handleSubmit():
handleSubmit(event) {
this.setState({ numberOfConsenting: this.consentingStudents.current.value });
alert(this.consentingStudents.current.value);
}

Input text in react form component does not allow text entry

I'm very new to react, and following a tutorial, made this Registration form (I just changed Bootstrap html with Materialize)
import React, {Component} from 'react';
class Register extends Component {
constructor() {
super();
this.state = {
email: '',
password: '',
errors: {}
};
this.handleChange = this.handleChange.bind(this);
}
handleChange (e) {
this.setState({
[e.target.name] : e.target.value
});
}
render() {
return (
<div>
<div className="row">
<div className="col s10 m6 offset-s1 offset-m3 ">
<form className="col s12 myform">
<h3 className="center"Register </h3>
<div className="row">
<div className="input-field col s12">
<input
id="email"
type="email"
value={this.state.email}
onChange = {this.handleChange}
/>
<label htmlFor="email">Email</label>
</div>
</div>
<div className="row">
<div className="input-field col s12">
<input
id="password"
type="password"
value={this.state.password}
onChange = {this.handleChange}
/>
<label htmlFor="password">Password</label>
</div>
</div>
<button className="btn mybtn waves-effect waves-light right" type="submit" name="action">Submit
<i className="mdi-content-send right"></i>
</button>
</form>
</div>
</div>
</div>
);
}
}
export default Register;
The problem is that I can not enter anything into the form and get no error in the console. So got really preplexed. Appreciate your hints.
As you have written:
handleChange (e) {
this.setState({
[e.target.name] : e.target.value // This line I mean.
});
}
So you just need to assign name prop to input tag because you have written e.target.name and your input name is available in the state but not available in input props.
So do it like this:
- Email input
<input
name="email"
id="email"
type="email"
value={this.state.email}
onChange = {this.handleChange}
/>
- Password input
<input
name="email"
id="email"
type="email"
value={this.state.email}
onChange = {this.handleChange}
/>
I hope it will be helped you and enjoy of react

Reactjs - Form validation

Can anybody help me, I'm really struggling with the validation form in React, I was trying also with some library but I'm doing something wrong.
I want to validate both to be required and number to be a number.
class Hello extends React.Component {
constructor() {
super();
this.state = {
firstname: '',
number: '',
};
}
onChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
}
onSubmit = (event) => {
event.preventDefault();
console.log('Submited');
}
render() {
return (
<div>
<form className="form-horizontal" onSubmit={this.onSubmit}>
<div className="form-group">
<label className="col-sm-2 control-label">Name</label>
<div className="col-sm-10">
<input type="text" name="firstname" className="form-control" onChange={this.onChange} placeholder="Firstname" />
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label">Number</label>
<div className="col-sm-10">
<input type="text" name="number" className="form-control" onChange={this.onChange} placeholder="Number" />
</div>
</div>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button type="submit" className="btn btn-success">Submit</button>
</div>
</div>
</form>
<h3>{this.state.firstname}</h3>
<h3>{this.state.number}</h3>
</div>
);
}
}

Resources