I have an Form Data input in react js application. I have tried below code to set Form Data state variable but value is showing as empty. Please check below code and advise how to do this...
Initial State :-
this.state = {
FormData: [{
UserId: 0,
FirstName: '',
LastName: '',
EmailId: '',
MobileNo: '',
DivisionId:'',
UserName: '',
Password: '',
ConfirmPassword: '',
RoleId: '',
UpdateUserName: localStorage.getItem("UserId"),
GridState: []
}],
};
Setting State Value in onchange event :-
onChangeHandler = (event) => {
let nam = event.target.name;
let val = event.target.value;
this.setState({[nam]: val});
}
HTML render:-
render() {
<div className="form-group row">
<label className="col-sm-1 col-form-label col-form-label-sm">First Name</label>
<div className="col-sm-3">
<input type="text" name="FormData.FirstName" className="form-control form-control-sm" id="TxtFirstName" placeholder="First Name" required onChange={this.onChangeHandler}/>
</div>
<label className="col-sm-1 col-form-label col-form-label-sm">Last Name</label>
<div className="col-sm-3">
<input type="text" name="FormData.LastName" className="form-control form-control-sm" id="TxtLastName" placeholder="Last Name" required onChange={this.onChangeHandler}/>
</div>
<label className="col-sm-1 col-form-label col-form-label-sm">Email Id</label>
<div className="col-sm-3">
<input type="email" name ="FormData.EmailId" className="form-control form-control-sm" id="TxtEmailId" placeholder="EmailId" required onChange={this.onChangeHandler}/>
</div>
</div>
<div className="form-group row">
<label className="col-sm-1 col-form-label col-form-label-sm">Mobile No</label>
<div className="col-sm-3">
<input type="text" name ="FormData.MobileNo" className="form-control form-control-sm" id="TxtMobileNo" placeholder="Mobile No" onChange={this.onChangeHandler} />
</div>
<label className="col-sm-1 col-form-label col-form-label-sm">User Name</label>
<div className="col-sm-3">
<input type="text" name ="FormData.UserName" className="form-control form-control-sm" id="TxtUserName" placeholder="User Name" required onChange={this.onChangeHandler}/>
</div>
</div>
<div className="form-group row">
<label className="col-sm-1 col-form-label col-form-label-sm">Password</label>
<div className="col-sm-3">
<input type="password" name ="FormData.Password" className="form-control form-control-sm" id="TxtPassword" placeholder="Password" required onChange={this.onChangeHandler}/>
</div>
Please check submit button handling code :-
onSubmitHandler = (event) => {
event.preventDefault();
console.log(JSON.stringify(this.state.FormData));
alert(JSON.stringify(this.state.FormData));
}
Flatten your state structure to be just the form fields
this.state = {
userId : 0,
firstName: '',
lastName : '',
emailId : '',
mobileNo : '',
divisionId :'',
userName : '',
password : '',
confirmPassword : '',
roleId : '',
updateUserName : localStorage.getItem("UserId"),
gridState : []
};
Leave onChangeHandler as-is since it handles a flat state structure already.
Update onSubmitHandler to stringify the state object representing the form fields
onSubmitHandler = (event) => {
event.preventDefault();
console.log(JSON.stringify(this.state));
alert(JSON.stringify(this.state));
}
Update form field names to match that in state. Example:
<input
type="text"
name="firstName" // <-- should match key in state
className="form-control form-control-sm"
id="TxtFirstName"
placeholder="First Name"
required
onChange={this.onChangeHandler}
/>
Note: camelCased all keys/names by normal naming convention.
The value of name in component's state and in HTML are not the same -:
In HTML it is -:
FormData.UserId
similarly for all other fields....
In JS it is only -:
UserId
similarly for all other fields....
FormData prefix is not there in state
you can do something like this -:
onChangeHandler = ({target: {name, value} }) => {
name = name.split(".")[1];
const FormData = {...this.state.FormData, [name]: value};
this.setState(FormData);
}
Related
Im trying to use post data but the only thing im getting back from the form is the username and password, What am i doing wrong? i want to get the teacher data too inside the state like fname, lname, mname etc. Also why is it only the username and password is getting posted or serialized. Thanks so much in advance
class Teachers extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedData: {},
tableData: [{
id: '',
email: '',
password: '',
}],
username: '',
password: '',
teacher: [{
employeeNo:'',
prefixName: '',
fname: '',
lname: '',
middleInitial: '',
sex: '',
citizenship: '',
status: '',
permanentAddress: '',
presentAddress: '',
bday: '',
contactNo: '',
emailAdd: '',
emergencyContactNo: '',
}],
}
this.editedData = params => {
console.log(params);
};
this.toggleModal = this.toggleModal.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.addNotification = this.addNotification.bind(this);
this.handleChange = this.handleChange.bind(this);
}
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
};
//request the token
async handleSubmit(event) {
event.preventDefault();
const getCred = await fetch('http://tfismartasp-001-site10.btempurl.com/api/Teacher/Register', {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'ApiKey': "Secret"
},
method: "POST",
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
prefixName: this.state.teacher.prefixName,
fname: this.state.teacher.fname,
lname: this.state.teacher.lname,
middleInitial: this.state.teacher.middleInitial,
sex: this.state.teacher.sex,
citizenship: this.state.teacher.citizenship,
status: this.state.teacher.Status,
permanentAddress: this.state.teacher.permanentAddress,
PresentAddress: this.state.teacher.presentAddress,
bday: this.state.teacher.bday,
contactNo: this.state.teacher.contactNo,
emailAdd: this.state.teacher.emailAdd,
emergencyContactNo: this.state.teacher.emergencyContactNo,
}),
});
const data = await getCred.json();
console.log(data);
}
<Modal isOpen={this.state.modalDialog} className="modal-lg" fade={false} toggle={() => this.toggleModal("modalDialog")}>
<ModalHeader toggle={() => this.toggleModal("modalDialog")}>
Edit Profile
</ModalHeader>
<form className="margin-bottom-0" onSubmit={this.handleSubmit}>
<ModalBody>
<h3><label className="control-label">Personal Information </label></h3>
<label className="control-label">Name <span className="text-danger">*</span></label>
<div className="row row-space-10">
<div className="col-md-2 m-b-15">
<input type="text" className="form-control" placeholder="Prefix" name="prefixName" value={this.state.teacher.prefixName} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<input type="text" className="form-control" placeholder="First name" name="fname" value={this.state.teacher.fname} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<input type="text" className="form-control" placeholder="Last name" name="lname" value={this.state.teacher.lname} onChange={this.handleChange} required="" />
</div>
<div className="col-md-2 m-b-15">
<input type="text" className="form-control" placeholder="Middle name" name="middleInitial" value={this.state.teacher.middleInitial} onChange={this.handleChange} required="" />
</div>
</div>
<div className="row row-space-10">
<div className="col-md-4 m-b-15">
<label className="control-label">Gender <span className="text-danger">*</span></label>
<select className="form-control" name="sex">
<option value={this.state.teacher.sex} onChange={this.handleChange}>MALE</option>
<option value={this.state.teacher.sex} onChange={this.handleChange}>FEMALE</option>
</select>
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Birthdate <span className="text-danger">*</span></label>
<input type="date" className="form-control" placeholder="Birthdate" name="bday" value={this.state.teacher.bday} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Citizenship <span className="text-danger">*</span></label>
<input type="text" className="form-control" placeholder="Citizenship" name="citizenship" value={this.state.teacher.citizenship} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Status <span className="text-danger">*</span></label>
<select className="form-control" name="status" placeholder="status" >
<option value={this.state.teacher.status} onChange={this.handleChange}>Single</option>
<option value={this.state.teacher.status} onChange={this.handleChange}>Married</option>
</select>
</div>
</div>
<hr/>
<h3><label className="control-label">Account Information </label></h3>
<div className="row row-space-10">
<div className="col-md-4 m-b-15">
<label className="control-label">Employee Number <span className="text-danger">*</span></label>
<input type="text" className="form-control" placeholder="Employee No." name="employeeNo" value={this.state.teacher.employeeNo} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Username <span className="text-danger">*</span></label>
<input type="text" className="form-control" placeholder="Username" name="username" value={this.state.username} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Password <span className="text-danger">*</span></label>
<input type="password" className="form-control" placeholder="Password" name="password" value={this.state.password} onChange={this.handleChange} required="" />
</div>
</div>
<hr/>
<h3><label className="control-label">Contact Information </label></h3>
<div className="row row-space-10">
<div className="col-md-4 m-b-15">
<label className="control-label">Permanent Address <span className="text-danger">*</span></label>
<input type="text" className="form-control" placeholder="Permamnent Address" name="permanentAddress" value={this.state.teacher.permanentAddress} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Present Address <span className="text-danger">*</span></label>
<input type="text" className="form-control" placeholder="Present Address" name="presentAddress" value={this.state.teacher.presentAddress} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Contact Number <span className="text-danger">*</span></label>
<input type="text" className="form-control" placeholder="Contact No." name="contactNo" value={this.state.teacher.contactNo} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Email Address <span className="text-danger">*</span></label>
<input type="text" className="form-control" placeholder="Email Address" name="emailAdd" value={this.state.teacher.emailAdd} onChange={this.handleChange} required="" />
</div>
<div className="col-md-4 m-b-15">
<label className="control-label">Emergency Number <span className="text-danger">*</span></label>
<input type="text" className="form-control" placeholder="Emergency No." name="emergencyContactNo" value={this.state.teacher.emergencyContactNo} onChange={this.handleChange} required="" />
</div>
</div>
</ModalBody>
<ModalFooter>
<button onClick={() => {
this.addNotification('success', 'Success', 'All data has been successfully saved', 'bottom-right')
this.toggleModal("modalDialog")
}} className="btn btn-sm btn-success">Save</button>
<button
className="btn btn-white btn-sm"
onClick={() => this.toggleModal("modalDialog")} >
Close
</button>
</ModalFooter>
</form>
</Modal>
If you are talking about only one teacher object, you can change the teacher to an object. Just remove [ and ] between the teacher object.
I want to clear the input field after upload and submit the form.
I have checked couple of documentation, where its said after submitting the form I can return the initial state.
Here is my code
state = {
firstname: "",
lastname: "",
email: "",
file: null
};
onDrop = e => {
this.setState({ file: e.target.files[0] });
console.log({ file: e.target.files[0] });
};
handleChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
handleSubmit = async e => {
e.preventDefault();
console.log(this.state);
const formData = new FormData();
formData.append("file", this.state.file);
formData.append("upload_preset", process.env.REACT_APP_UPLOAD_PRESET);
const response = await axios.post(
`https://api.cloudinary.com/v1_1/${process.env.REACT_APP_CLOUD_NAME}/image/upload`,
formData
);
await this.props.addPerson({
variables: {
firstname: this.state.firstname,
lastname: this.state.lastname,
email: this.state.email,
image: response.data.url
},
refetchQueries: [{ query: getperson }]
});
this.setState({ firstname: " ", lastname: "", email: " ", file: null }); **this is where i retutn the initial state after submitting the form, but it did not work**
};
This is my form setup
<React.Fragment>
<div>
<form id="addPerson" onSubmit={this.handleSubmit}>
<div className="field">
<label> Firstname </label>
<input type="text" id="firstname" onChange={this.handleChange} />
</div>
<div className="field">
<label> Lastname </label>
<input type="text" id="lastname" onChange={this.handleChange} />
</div>
<div className="field">
<label> Email </label>
<input type="email" id="email" onChange={this.handleChange} />
</div>
<input type="file" onChange={this.onDrop} />
<button>Add Person</button>
</form>
</div>
</React.Fragment>
It doesn't work because your inputs are not fully controlled by react, If you want to control these inputs, you need to specify the value attribute like this :
<input type="text" id="firstname" value={this.state.firstname} onChange={this.handleChange}/>
<input type="text" id="lastname" value={this.state.lastname} onChange={this.handleChange}/>
Note that the file input is always uncontrolled in react (see the documentation), so you need to reset it manually by using a reference :
constructor() {
this.fileRef = React.createRef();
...
}
handleSubmit = async e => {
// Reset the file input
this.fileRef.current.value = '';
};
render() {
...
<input type="file" ref={this.fileRef} onChange={this.onDrop} />
...
}
You haven't set the value attribute in html input with state value.
Since the value attribute is set on our form element, the displayed value will always be this.state.value, making the React state the source of truth.
Since handleChange runs on every keystroke to update the React state, the displayed value will update as the user types.
With a controlled component, every state mutation will have an associated handler function. This makes it straightforward to modify or validate user input.
For more details please check here.
Use following code,
<React.Fragment>
<div>
<form id="addPerson" onSubmit={this.handleSubmit}>
<div className="field">
<label> Firstname </label>
<input type="text" id="firstname" value={this.state.firstname} onChange={this.handleChange} />
</div>
<div className="field">
<label> Lastname </label>
<input type="text" id="lastname" value={this.state.lastname} onChange={this.handleChange} />
</div>
<div className="field">
<label> Email </label>
<input type="email" id="email" value={this.state.email} onChange={this.handleChange} />
</div>
<input type="file" onChange={this.onDrop} />
<button>Add Person</button>
</form>
</div>
</React.Fragment>
Hope this will help you !!!
I have problem with assign from array to model. I want to assign firstName value from userFromDb and assign this value to firstName in model and the same with another values. I don't know how do this :(
User
export interface User{
id:string;
firstName:string;
lastName:string;
email:string;
password:string;
}
UpadateUserComponent.ts
userFromDb: Array<Object>;
model:User = {
id: '',
firstName: '',
lastName: '',
email: '',
password: ''}
ngOnInit() {
let id = this.route.snapshot.paramMap.get('id');
this.userService.getUser(id).subscribe(result => {
console.log(result)
this.userFromDb = result
console.log(this.userFromDb)
});
UpadateUserComponent.html
<div>
<form action="" #f="ngForm" (ngSubmit)="saveUser()" novalidate>
<div>
<label for="firstName">First Name: </label>
<input [(ngModel)]="model.firstName" type="text" id="firstName" name="firstName" placeholder="Name">
</div>
<div>
<label for="lastName">Last Name: </label>
<input [(ngModel)]="model.lastName" type="text" id="lastName" name="lastName" placeholder="Name" >
</div>
<div>
<label for="email">Email: </label>
<input [(ngModel)]="model.email" type="text" id="email" name="email" placeholder="Name" >
</div>
<div>
<label for="password">Password: </label>
<input [(ngModel)]="model.password" type="text" id="password" name="password" placeholder="Name" >
</div>
<button type="submit">Submit</button>
</form>
</div>
I do not know what your database structure looks like, but lets say it is the same as your frontend...
First I am not sure why your userFromDb is an array, would it return more than one user?
If you just want to insert the values then the simplest would be:
this.userService.getUser(id).subscribe(result => {
console.log(result)
this.userFromDb = result
this.model.firstName = this.userFromDB[0].firstName
// same with other values here
console.log(this.userFromDb)
});
this.userService.getUser(id).subscribe(result => {
console.log(result);
this.userFromDb:User = result[0];
console.log(this.userFromDb);
});
HTML
<div>
<form action="" #f="ngForm" (ngSubmit)="saveUser()" novalidate>
<div>
<label for="firstName">First Name: </label>
<input [(ngModel)]="userFromDb.firstName" type="text" id="firstName" name="firstName" placeholder="Name">
</div>
<div>
<label for="lastName">Last Name: </label>
<input [(ngModel)]="model.lastName" type="text" id="lastName" name="lastName" placeholder="Name" >
</div>
<div>
<label for="email">Email: </label>
<input [(ngModel)]="userFromDb.email" type="text" id="email" name="email" placeholder="Name" >
</div>
<div>
<label for="password">Password: </label>
<input [(ngModel)]="userFromDb.password" type="text" id="password" name="password" placeholder="Name" >
</div>
<button type="submit">Submit</button>
</form>
</div>
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);
}
This form I'm doing in a React app was working fine until I added a few more fields. I can't figure out why I wouldn't be able to type into "first Name", "middle", or "last name" on the form.
Basically, I've tried adding the fields with the exact process that I added the other fields with, but it's just not working and I keep looking over the code and can't find out what's going on. I add everything throughout the code that all the other fields have.
import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom';
import { compose } from 'recompose';
import { withFirebase } from '../Firebase';
import * as ROUTES from '../../constants/routes';
import * as ROLES from '../../constants/roles';
const SignUpPage = () => (
<div>
<h1>SignUp</h1>
<SignUpForm />
</div>
);
const INITIAL_STATE = {
username: '',
firstName: '',
middleName: '',
lastName: '',
email: '',
passwordOne: '',
passwordTwo: '',
isAdmin: false,
mailingAddress: '',
city: '',
state: '',
zip: '',
error: null,
};
class SignUpFormBase extends Component {
constructor(props) {
super(props);
this.state = { ...INITIAL_STATE };
}
onChange = event => {
this.setState({ [event.target.name]: event.target.value });
};
onSubmit = event => {
const { username, firstName, middleName, lastName, email, passwordOne, isAdmin, mailingAddress, city, state, zip } = this.state;
const roles = {};
if (isAdmin) {
roles[ROLES.ADMIN] = ROLES.ADMIN;
}
this.props.firebase
.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
// Create a user in your Firebase realtime database
return this.props.firebase
.user(authUser.user.uid)
.set({
username,
firstName,
middleName,
lastName,
email,
roles,
mailingAddress,
city,
state,
zip,
});
})
.then(() => {
return this.props.firebase.doSendEmailVerification();
})
.then(() => {
this.setState({ ...INITIAL_STATE });
this.props.history.push(ROUTES.HOME);
})
.catch(error => {
this.setState({ error });
});
event.preventDefault();
}
onChangeCheckbox = event => {
this.setState({ [event.target.name]: event.target.checked });
};
onChangeSelection = event => {
this.setState({ [event.target.name]: event.target.selected });
};
render() {
const {
username,
firstName,
middleName,
lastName,
email,
passwordOne,
passwordTwo,
isAdmin,
mailingAddress,
city,
state,
zip,
error,
} = this.state;
const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === '' ||
username === '' ||
email === '' ||
firstName === '' ||
lastName === ''||
mailingAddress === '' ||
city === '' ||
state === '' ||
zip === '';
return (
<form onSubmit={this.onSubmit}>
<div class="form-row">
<div class="form-group col-md-4">
<input
name="username"
value={username}
onChange={this.onChange}
type="text"
placeholder="Username"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<input
name="firstname"
value={firstName}
onChange={this.onChange}
type="text"
placeholder="First Name"
class="form-control"
/>
</div>
<div class="form-group col-md-4">
<input
name="middlename"
value={middleName}
onChange={this.onChange}
type="text"
placeholder="Middle Name"
class="form-control"
/>
</div>
<div class="form-group col-md-4">
<input
name="lastname"
value={lastName}
onChange={this.onChange}
type="text"
placeholder="Last Name"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<input
name="email"
value={email}
onChange={this.onChange}
type="text"
placeholder="Email Address"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<input
name="passwordOne"
value={passwordOne}
onChange={this.onChange}
type="password"
placeholder="Password"
class="form-control"
/>
</div>
<div class="form-group col-md-6">
<input
name="passwordTwo"
value={passwordTwo}
onChange={this.onChange}
type="password"
placeholder="Confirm Password"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-2">
<label>
Admin:
<input
name="isAdmin"
type="checkbox"
checked={isAdmin}
onChange={this.onChangeCheckbox}
/>
</label>
</div>
</div>
<br />
<div class="form-row">
<div class="form-group col-md-4">
Mailing Address:
<input
name="mailingAddress"
value={mailingAddress}
onChange={this.onChange}
type="text"
placeholder="Street Address"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<input
name="city"
value={city}
onChange={this.onChange}
type="text"
placeholder="City"
class="form-control"
/>
</div>
<div class="form-group col-md-2">
<select id="inputState" class="form-control" value={state} onChange={this.onChangeSelection}>
<option selected>Choose a state</option>
<option>...</option>
</select>
</div>
<div class="form-group col-md-1">
<input
name="zip"
value={zip}
onChange={this.onChange}
type="text"
placeholder="Zip Code"
class="form-control"
/>
</div>
</div>
<button disabled={isInvalid} type="submit" class="btn btn-primary">
Sign Up
</button>
{error && <p>{error.message}</p>}
</form>
);
}
}
const SignUpLink = () => (
<p>
Don't have an account? <Link to={ROUTES.SIGN_UP}>Sign Up</Link>
</p>
);
const SignUpForm = compose(
withRouter,
withFirebase,
)(SignUpFormBase);
export default SignUpPage;
export { SignUpForm, SignUpLink };
I just want the name fields to register keystrokes like the rest of the form can. Everything else works. I don't get why first, middle, and last name will only focus.
Try changing value to defaultValue. defaultValue only gets set on initial load for a form. After that, it won't get "naturally" updated because the intent was only to set an initial default value.
import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom';
import { compose } from 'recompose';
import { withFirebase } from '../Firebase';
import * as ROUTES from '../../constants/routes';
import * as ROLES from '../../constants/roles';
const SignUpPage = () => (
<div>
<h1>SignUp</h1>
<SignUpForm />
</div>
);
const INITIAL_STATE = {
username: '',
firstName: '',
middleName: '',
lastName: '',
email: '',
passwordOne: '',
passwordTwo: '',
isAdmin: false,
mailingAddress: '',
city: '',
state: '',
zip: '',
error: null,
};
class SignUpFormBase extends Component {
constructor(props) {
super(props);
this.state = { ...INITIAL_STATE };
}
onChange = event => {
this.setState({ [event.target.name]: event.target.value });
};
onSubmit = event => {
const { username, firstName, middleName, lastName, email, passwordOne, isAdmin, mailingAddress, city, state, zip } = this.state;
const roles = {};
if (isAdmin) {
roles[ROLES.ADMIN] = ROLES.ADMIN;
}
this.props.firebase
.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
// Create a user in your Firebase realtime database
return this.props.firebase
.user(authUser.user.uid)
.set({
username,
firstName,
middleName,
lastName,
email,
roles,
mailingAddress,
city,
state,
zip,
});
})
.then(() => {
return this.props.firebase.doSendEmailVerification();
})
.then(() => {
this.setState({ ...INITIAL_STATE });
this.props.history.push(ROUTES.HOME);
})
.catch(error => {
this.setState({ error });
});
event.preventDefault();
}
onChangeCheckbox = event => {
this.setState({ [event.target.name]: event.target.checked });
};
onChangeSelection = event => {
this.setState({ [event.target.name]: event.target.selected });
};
render() {
const {
username,
firstName,
middleName,
lastName,
email,
passwordOne,
passwordTwo,
isAdmin,
mailingAddress,
city,
state,
zip,
error,
} = this.state;
const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === '' ||
username === '' ||
email === '' ||
firstName === '' ||
lastName === ''||
mailingAddress === '' ||
city === '' ||
state === '' ||
zip === '';
return (
<form onSubmit={this.onSubmit}>
<div class="form-row">
<div class="form-group col-md-4">
<input
name="username"
defaultValue={username}
onChange={this.onChange}
type="text"
placeholder="Username"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<input
name="firstname"
defaultValue={firstName}
onChange={this.onChange}
type="text"
placeholder="First Name"
class="form-control"
/>
</div>
<div class="form-group col-md-4">
<input
name="middlename"
value={middleName}
onChange={this.onChange}
type="text"
placeholder="Middle Name"
class="form-control"
/>
</div>
<div class="form-group col-md-4">
<input
name="lastname"
defaultValue={lastName}
onChange={this.onChange}
type="text"
placeholder="Last Name"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<input
name="email"
value={email}
onChange={this.onChange}
type="text"
placeholder="Email Address"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<input
name="passwordOne"
value={passwordOne}
onChange={this.onChange}
type="password"
placeholder="Password"
class="form-control"
/>
</div>
<div class="form-group col-md-6">
<input
name="passwordTwo"
value={passwordTwo}
onChange={this.onChange}
type="password"
placeholder="Confirm Password"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-2">
<label>
Admin:
<input
name="isAdmin"
type="checkbox"
checked={isAdmin}
onChange={this.onChangeCheckbox}
/>
</label>
</div>
</div>
<br />
<div class="form-row">
<div class="form-group col-md-4">
Mailing Address:
<input
name="mailingAddress"
value={mailingAddress}
onChange={this.onChange}
type="text"
placeholder="Street Address"
class="form-control"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<input
name="city"
value={city}
onChange={this.onChange}
type="text"
placeholder="City"
class="form-control"
/>
</div>
<div class="form-group col-md-2">
<select id="inputState" class="form-control" value={state} onChange={this.onChangeSelection}>
<option selected>Choose a state</option>
<option>...</option>
</select>
</div>
<div class="form-group col-md-1">
<input
name="zip"
value={zip}
onChange={this.onChange}
type="text"
placeholder="Zip Code"
class="form-control"
/>
</div>
</div>
<button disabled={isInvalid} type="submit" class="btn btn-primary">
Sign Up
</button>
{error && <p>{error.message}</p>}
</form>
);
}
}
const SignUpLink = () => (
<p>
Don't have an account? <Link to={ROUTES.SIGN_UP}>Sign Up</Link>
</p>
);
const SignUpForm = compose(
withRouter,
withFirebase,
)(SignUpFormBase);
export default SignUpPage;
export { SignUpForm, SignUpLink };