How save input values and checked information in state? - reactjs

I made such a project through context. But I can't save the values of checkbox and select options in memory. All other inputs work correctly. CRUD operations are fine, but when I select and confirm the gender, then when I try to edit the details of that contact, the gender of the contact is not visible. Also, the ``I want to receive information'' button at the bottom does not appear checked.
import React, { useState } from "react";
import { useContext } from "react";
import { GlobalContext } from "../../context/GlobalState";
import { useNavigate } from "react-router-dom";
import { NavLink } from "react-router-dom";
import { v4 as uuidv4 } from 'uuid';
const Form = () => {
const { ADD_CONTACT } = useContext(GlobalContext);
const [contact, setContact] = useState({
id: uuidv4(),
name: "",
surname: "",
fatherName: "",
specialty: "",
email: "",
gender: "",
updatesNotification:''
});
const { name, surname, fatherName, specialty, email } = contact;
let history = useNavigate();
const onSubmit = (e) => {
e.preventDefault();
if (contact) {
ADD_CONTACT(contact);
history("/contacts");
console.log(contact);
}
};
return (
<form onSubmit={onSubmit}>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Name</label>
<div class="col-sm-10">
<input
class="form-control"
name="name"
required
value={name}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Surname</label>
<div class="col-sm-10">
<input
class="form-control"
name="surname"
required
value={surname}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Father Name</label>
<div class="col-sm-10">
<input
class="form-control"
name="fatherName"
required
value={fatherName}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input
class="form-control"
name="email"
required
value={email}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Specialty</label>
<div class="col-sm-10">
<input
class="form-control"
name="specialty"
required
value={specialty}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div className="mb-3 row">
<label class="col-sm-2 col-form-label">Job</label>
<div className="col-sm-10 d-flex justify-content-center align-items-center">
<select class="form-select" aria-label="Default select example">
<option selected>Bakalavr</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</div>
<div className="mb-3 row">
<label class="col-sm-2 col-form-label">Gender</label>
<div className="col-sm-10">
<div class="form-check form-check-inline ">
<input
class="form-check-input"
type="radio"
name="gender"
value="male"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
<label class="form-check-label">Kisi</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="gender"
value="female"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
<label class="form-check-label">Female</label>
</div>
</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" />
<label class="form-check-label" for="flexCheckDefault">
I want to be notified of updates
</label>
</div>
<button type="submit" class="btn btn-primary">
Create a new contact
</button>
<NavLink to="/contacts" className="btn btn-danger m-2">
Cancel
</NavLink>
</form>
);
};
export default Form;
import React from "react";
import { NavLink } from "react-router-dom";
import { useContext, useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { GlobalContext } from "../../context/GlobalState";
const EditContactForm = () => {
const { contacts, UPDATE_CONTACT } = useContext(GlobalContext);
const [selectedContact, setSelectedContact] = useState({
id: "",
name: "",
surname: "",
fatherName: "",
specialty: "",
email: "",
gender: "",
});
const history = useNavigate();
const {id} = useParams();
useEffect(() => {
const userId = id;
const selectedContact = contacts.find((user) => String(user.id) === userId);
if (selectedContact) {
setSelectedContact(selectedContact);
}
}, [id, contacts]);
function onSubmit(e) {
e.preventDefault();
UPDATE_CONTACT(selectedContact);
console.log("new user edited:", selectedContact);
history("/contacts");
}
const handleOnChange = (e) => {
setSelectedContact(selectedContact => ({
...selectedContact,
[e.target.name]: e.target.value
}));
};
return (
<div>
<form onSubmit={onSubmit}>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Name</label>
<div class="col-sm-10">
<input
class="form-control"
name="name"
required
value={selectedContact?.name ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Surname</label>
<div class="col-sm-10">
<input
class="form-control"
name="surname"
required
value={selectedContact?.surname ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Father Name</label>
<div class="col-sm-10">
<input
class="form-control"
name="fatherName"
required
value={selectedContact?.fatherName ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input
class="form-control"
name="email"
required
value={selectedContact?.email ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">Specialty</label>
<div class="col-sm-10">
<input
class="form-control"
name="specialty"
required
value={selectedContact?.specialty ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div className="mb-3 row">
<label class="col-sm-2 col-form-label">Vezife</label>
<div className="col-sm-10 d-flex justify-content-center align-items-center">
<select class="form-select" aria-label="Default select example">
<option selected>Bakalavr</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</div>
<div className="mb-3 row">
<label class="col-sm-2 col-form-label">Gender</label>
<div className="col-sm-10">
<div class="form-check form-check-inline ">
<input
class="form-check-input"
type="radio"
name="gender"
required
value="male"
onChange={handleOnChange}
/>
<label class="form-check-label">Male</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="gender"
value="female"
onChange={handleOnChange}
/>
<label class="form-check-label">Female</label>
</div>
</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" />
<label class="form-check-label" for="flexCheckDefault">
I want to be notified of updates
</label>
</div>
<button type="submit" class="btn btn-primary">
Update a contact
</button>
<NavLink to="/contacts" className="btn btn-danger m-2">
Cancel
</NavLink>
</form>
</div>
);
};
export default EditContactForm;
enter image description here
enter image description here
sandbox: https://codesandbox.io/s/task1-w5zvg4?file=/src/App.js

When working with checkbox you have to look for e.target.checked to access if it is checked or not.
You can try something like this:
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="gender"
id="female"
checked={contact.gender === "female"}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.checked ? e.target.id : "" })
}
/>
<label htmlFor="female" class="form-check-label">Female</label>
</div>
For the select, you can achieve this like this:
const selectOptions = [
{label: "One", value: 1},
{label: "Two", value: 2},
{label: "Three", value: 3},
]
const Test = () => {
const onChange = (e) => setContact({ ...contact, [e.target.name]: e.target.value })
return <>
<label class="col-sm-2 col-form-label">Job</label>
<div className="col-sm-10 d-flex justify-content-center align-items-center">
<select value={contact.test} onChange={onChange} name="test" class="form-select" aria-label="Default select example">
{selectOptions.map(item => (
<option key={item.value} value={item.value}>{item.label}</option>
))}
</select>
</div>
</>
}

Related

Show or hide on multiple element using class in React

I am using the class component here Consider selecting Yes or No value depending on whether to show or hide the div.
I wanted to do the same thing with multiple div. But here if I am selecting yes then both the div are open. And not close to clicked on no value.
Here is my code:
class PersonalInfo extends Component {
constructor(props) {
super(props);
this.divstatus1 = this.divstatus1.bind(this);
this.divstatus2 = this.divstatus2.bind(this);
this.state = {
value1: 'no',
value2: 'no'
};
}
divstatus1 = (e) => {
this.setState({ value1: e.target.value1 });
}
divstatus2 = (e) => {
this.setState({ value2: e.target.value2 });
}
render() {
return (
<div>
<h3 className="showbase_header">Passport Details</h3>
<div className="form-group">
<label htmlFor="orderby"> Do you have passport ?</label>
<select className="form-control orderby" onChange={this.divstatus1}>
<option value="" selected>Select</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
<br></br>
<div className={this.state.value1} >
<div className="row">
<div className="col-md-6 form-group">
<label htmlFor="name">Passport Number
<span className="required">*</span>
</label>
<input type="text" id="firstname" aria-required="true" size={30} name="firstname" className="form-control" placeholder="" />
</div>
<div className="col-md-6 form-group">
<label htmlFor="name">Place Of Issue
<span className="required">*</span>
</label>
<input type="text" id="lastname" aria-required="true" size={30} name="lastname" className="form-control" placeholder="" />
</div>
</div>
<div className="row">
<div className="col-sm-6 form-group">
<label htmlFor="expirydate">Expiry Date
<span className="required">*</span>
</label>
<input type="date" id="expirydate" aria-required="true" size={30} name="expirydate" className="form-control" placeholder="" />
</div>
<div className="col-sm-6 form-group">
<label htmlFor="issuedate">Issue Date
<span className="required">*</span>
</label>
<input type="date" id="issuedate" aria-required="true" size={30} name="issuedate" className="form-control" placeholder="" />
</div>
</div>
</div>
</div>
<div className="form-group">
<h3 className="showbase_header">Representation</h3>
<select className="form-control orderby" onChange={this.divstatus2}>
<option value="">Select</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select><br />
<div className={this.state.value2} >
<div class="row">
<div className="col-sm-6 form-group">
<label htmlFor="name">Name
<span className="required">*</span>
</label>
<input type="text" id="name" aria-required="true" size={30} name="name" className="form-control" placeholder="" />
</div>
<div className="col-sm-6 form-group">
<label htmlFor="number">Contact Number
<span className="required">*</span>
</label>
<input type="number" id="name" aria-required="true" size={30} name="number" className="form-control" placeholder="" />
</div>
</div>
</div>
</div>
</div>
);
}
}
export default PersonalInfo;
I have added in main.css
.yes{display: block;}
.no{display: none;}
Can you try this,
divstatus1 = (e) => {
this.setState({ value1: e.target.value });
}
divstatus2 = (e) => {
this.setState({ value2: e.target.value });
}
option does not have an attribute called value1 or value2

What could cause html select element not to render on the browser?

I have a form in my react project with few input tags
and select tags. On the browser the inputs are rendering
but the select tags are not rendering. I am using materialize css
for the styling. I inspect the elements, the select element is showing
on the elements inspection pane and there is no console error about it.
What could be the problem and the possible
solution? The codes is as show below with screen shots.
import React, { useState, useEffect, useRef } from 'react';
import { useDispatch } from 'react-redux';
import M from 'materialize-css/dist/js/materialize'
function Register() {
const initialState = {
pin: '',
serial_num: '',
last_name: '',
first_name: '',
date: '',
gender: 'male',
school: '',
class: '',
photo: ''
}
const photoRef = useRef();
const dispatch = useDispatch();
useEffect(() => {
const elems = document.querySelectorAll('.datepicker');
M.Datepicker.init(elems, {
autoClose: true
});
}, []);
const [regState, setRegState] = useState(initialState)
const onChange = e => {
setRegState({ ...regState, [e.target.name]: e.target.value });
}
const onSubmit = e => {
// dispatch();
setRegState({...regState,
photo: photoRef.current.files[0].name
})
console.log(regState)
console.log(photoRef.current.files[0].name);
setRegState({ ...initialState });
e.preventDefault();
}
return (
<div className="row">
<form method='POST'
onSubmit={onSubmit}
className="col s12"
encType="multipart/form-data"
>
<div className="input-field col s12">
<input id="serial_num" type="text"
className="validate" name="serial_num"
min="13" max="17" onChange={onChange} required
value={regState.serial_num}
/>
<label htmlFor="serial_num">Serial Number</label>
</div>
<div className="input-field col s12">
<input id="pin" type="password"
className="validate" name="pin"
min="10" max="15" onChange={onChange} required
value={regState.pin}
/>
<label htmlFor="pin">Pin</label>
</div>
<div className="input-field col s12">
<input id="last_name" type="text"
className="validate" name="last_name"
onChange={onChange} required
value={regState.last_name}
/>
<label htmlFor="last_name">Last Name</label>
</div>
<div className="input-field col s12">
<input id="first_name" type="text"
className="validate" name="first_name"
onChange={onChange} required
value={regState.first_name}
/>
<label htmlFor="first_name">First Name</label>
</div>
<div className="input-field col s12">
<input id="date" type="text"
className="validate datepicker" name="date"
onChange={onChange} required
value={regState.date}
/>
<label htmlFor="date">Date of Birth</label>
</div>
<div className="input-field col s12">
<label>
<input name="gender" type="radio" checked value='male' onChange={onChange} />
<span>Male</span>
</label>
</div>
<div className="input-field col s12">
<label>
<input name="gender" type="radio" value='female' onChange={onChange} />
<span>Female</span>
</label>
</div>
<div className="input-field col s12">
<select name='school' id="school" value={regState.school} onChange={onChange} >
<option value="" >Select School</option>
<option value="nursery" >Nursery School</option>
<option value="primary" >Primary School</option>
<option value="secondary" >Secondary School</option>
</select>
<label htmlFor="school">Select School</label>
</div>
<div className="input-field col s12">
<select name='class' id="class" value={regState.class} onChange={onChange} >
<option value="" >Select Class</option>
</select>
<label htmlFor="class">Select Class</label>
</div>
<div className="input-field col s12">
<input id="photo" type="file"
className="validate" name="photo"
ref={photoRef}
/>
<label htmlFor="photo">Photo</label>
</div>
<button className="btn waves-effect waves-light" type="submit" name="action">Submit
<i className="material-icons right">send</i>
</button>
</form>
</div>
)
}
Select needs to be initialized - after it's been added to the DOM, and every subsequent time it is rendered:
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
FYI, Materialize hides the native select (display:none) and only generates the new select (actually a dropdown triggered by a text input) when the init runs. You can also use .browser-default on the select and bypass the init and the materialize styling.

React conditional divs with hooks

I am creating a signup form that will render differently depending on whether the person signing up chooses Post a project or Work on a project from the very first div in the form.
How can I render each div that follows in the form-group conditionally based on what is selected in the first div? I am using hooks and I have found that most examples are for the extends Component approach.
My form:
const signUpForm = () => (
<form onSubmit={clickSubmit}>
<div className="form-group">
<select onChange={handleChange("role")} class="form-control">
<option selected>I want to...</option>
<option>Post a project</option>
<option>Work on a project</option>
</select>
</div>
<div className="form-group">
<input
onChange={handleChange("name")}
type="text"
placeholder="Name"
className="form-control"
value={name}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("email")}
type="email"
placeholder="Email"
className="form-control"
value={email}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("password")}
type="password"
placeholder="Password"
className="form-control"
value={password}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("studying")}
type="text"
placeholder="I'm studying..."
className="form-control"
value={studying}
/>
</div>
<div>
<div>{createInputs()}</div>
<button
className="btn btn-outline-primary btn-sm mb-3"
onClick={addSkill}
type="text"
>
Add more skills
</button>
</div>
<button onClick={clickSubmit} className="btn btn-primary" type="submit">
Sign Up
</button>
</form>
);
State:
const Signup = () => {
const [values, setValues] = useState({
name: "",
email: "",
password: "",
studying: "",
skills: [""],
error: "",
success: "",
role: ""
});
const { name, email, password, studying, skills, success, error, role } = values;
handleChange():
const handleChange = name => event => {
setValues({ ...values, error: false, [name]: event.target.value });
};
You should first divide the signUp in two parts and then call second function based on value of "role" from state.
The idea is to return the divs from second function based on state of first input.
const signUpForm = () => (
<form onSubmit={clickSubmit}>
<div className="form-group">
<select onChange={handleChange("role")} class="form-control">
<option selected>I want to...</option>
<option>Post a project</option>
<option>Work on a project</option>
</select>
</div>
{this.renderInput()}
<button onClick={clickSubmit} className="btn btn-primary" type="submit">
Sign Up
</button>
</form>
);
renderInput() {
if (values.role === "post") {
return (
<div className="form-group">
<input onChange={handleChange("name")} type="text" placeholder="Name" className="form-control" value={name} />
</div>
<div className="form-group">
<input onChange={handleChange("email")} type="email" placeholder="Email" className="form-control" value={email} />
</div>
<div className="form-group">
<input onChange={handleChange("password")} type="password" placeholder="Password" className="form-control" value={password} />
</div>
<div className="form-group">
<input onChange={handleChange("studying")} type="text" placeholder="I'm studying..." className="form-control" value={studying} />
</div>
<div>
<div>{createInputs()}</div>
<button className="btn btn-outline-primary btn-sm mb-3" onClick={addSkill} type="text">
Add more skills
</button>
</div>
);
}
}
You want to test the role state value is truthy/falsey and render the rest of your form on that value.
const SignUpForm = () => (
<form onSubmit={clickSubmit}>
<div className="form-group">
<select
defaultValue='unselected' // set default value here
onChange={handleChange("role")}
className="form-control" // fix className here, class alone isn't correct in react
>
<option value='unselected'>I want to...</option>
<option value='post'>Post a project</option>
<option value='work'>Work on a project</option>
</select>
</div>
{!!role && (
<Fragment>
<div className="form-group">
<input
onChange={handleChange("name")}
type="text"
placeholder="Name"
className="form-control"
value={name}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("email")}
type="email"
placeholder="Email"
className="form-control"
value={email}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("password")}
type="password"
placeholder="Password"
className="form-control"
value={password}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("studying")}
type="text"
placeholder="I'm studying..."
className="form-control"
value={studying}
/>
</div>
<div>
<div>{createInputs()}</div>
<button
className="btn btn-outline-primary btn-sm mb-3"
onClick={addSkill}
type="text"
>
Add more skills
</button>
</div>
</Fragment>
)}
<button onClick={clickSubmit} className="btn btn-primary" type="submit">
Sign Up
</button>
</form>
);

How to bind value from dropdown list in React?

I'm trying to get the value of the id in my dropdown list to post to an API and i'm not entirely sure how to do that.I Any help would be appreciated
I've tried using the onchange with a handleChange function but it doesn't do anything. The react files are below for the form and for posting of the form
import React from "react";
import { updateUsers, fetchUsers } from "./actions/appactions";
import FormChange from "./formchange";
var createReactClass = require("create-react-class");
const Update = createReactClass({
getIntitialState() {
return {
users: []
};
},
componentWillReceiveProps(props) {
this.setState(props);
},
componentDidMount() {
fetchUsers(this.props.match.params.usersId)
.then(resp => resp.json())
.then(data => {
// this.setState({
// users: data
// });
this.setState(state => {
state.users = data;
return state;
});
})
.catch(err => {
console.error("error", err);
});
},
handleSubmit(data) {
updateUsers(this.state.users.id, data);
},
render() {
return (
<div>
<FormChange
onSubmit={this.handleSubmit}
password={this.state.users.password}
/>
</div>
);
}
});
export default Update;
import React from "react";
import { Link } from "react-router-dom";
var createReactClass = require("create-react-class");
const Form2 = createReactClass({
//setting initial state
getInitialState() {
return {
customerName: this.props.customerName,
email: this.props.email,
businessName: this.props.businessName,
address: this.props.address,
city: this.props.city,
lga: this.props.lga,
url: this.props.url,
description: this.props.description,
obj: []
};
},
componentDidMount() {
this.fetchOptions();
},
fetchOptions() {
fetch("https://localhost:44341/api/categories")
.then(res => res.json())
.then(json => {
this.setState({
obj: json
});
});
},
handleCustomerChange(e) {
this.setState({
customerName: e.target.value
});
},
handleEmailChange(e) {
this.setState({
email: e.target.value
});
},
handleBusinessChange(e) {
this.setState({
businessName: e.target.value
});
},
handleAddressChange(e) {
this.setState({
address: e.target.value
});
},
handleCityChange(e) {
this.setState({
city: e.target.value
});
},
handleLgaChange(e) {
this.setState({
lga: e.target.value
});
},
handleUrlChange(e) {
this.setState({
url: e.target.value
});
},
handleDescriptionChange(e) {
this.setState({
description: e.target.value
});
},
handleCatChange(e) {
this.setState({
obj: e.target.value
});
},
handleSubmit(e) {
e.preventDefault();
this.props.onSubmit(this.state);
},
render() {
return (
<form
name="categories_post"
className="form-horizontal"
onSubmit={this.handleSubmit}
>
<div id="business_post">
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="customerName"
>
Customer Name
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.customerName}
onChange={this.handleCustomerChange}
id="customerName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="email">
Email
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.email}
onChange={this.handleEmailChange}
id="email"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="businessName"
>
Business Name
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.businessName}
onChange={this.handleBusinessChange}
id="businessName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="address"
>
Address
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.address}
onChange={this.handleAddressChange}
id="address"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="city">
City
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.city}
onChange={this.handleCityChange}
id="city"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="lga">
LGA
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.lga}
onChange={this.handleLgaChange}
id="lga"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="url">
URL
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.url}
onChange={this.handleUrlChange}
id="url"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="description"
>
Description
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.description}
onChange={this.handleDescriptionChange}
id="description"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="email">
categories name
</label>
<div className="drop-down">
<select>
{this.state.obj.map(obj => {
return (
<option key={obj.id} value={obj.id}>
{obj.categoryName}
</option>
);
})}
</select>
</div>
</div>
<div className="form-group">
<div className="col-sm-2" />
<div className="col-sm-10">
<button
type="submit"
id="categoriesSubmit"
className="btn btn-default"
>
submit
</button>
</div>
</div>
<div className="form-group">
<div className="col-sm-2" />
<div className="col-sm-10">
<button className="btn btn-danger .mt-3">
<Link to="/business">Home</Link>
</button>
</div>
</div>
</div>
</form>
);
}
});
export default Form2;
UPDATE
Use react-select, It is able to handle id and value elegantly.
Can you give it a try?
npm install react-select
import React from "react";
import { Link } from "react-router-dom";
var createReactClass = require("create-react-class");
import Select from 'react-select';
const Form2 = createReactClass({
//setting initial state
getInitialState() {
return {
customerName: this.props.customerName,
email: this.props.email,
businessName: this.props.businessName,
address: this.props.address,
city: this.props.city,
lga: this.props.lga,
url: this.props.url,
description: this.props.description,
obj: []
};
},
componentDidMount() {
this.fetchOptions();
},
fetchOptions() {
fetch("https://localhost:44341/api/categories")
.then(res => res.json())
.then(json => {
this.setState({
obj: json
});
});
},
handleCustomerChange(e) {
this.setState({
customerName: e.target.value
});
},
handleEmailChange(e) {
this.setState({
email: e.target.value
});
},
handleBusinessChange(e) {
this.setState({
businessName: e.target.value
});
},
handleAddressChange(e) {
this.setState({
address: e.target.value
});
},
handleCityChange(e) {
this.setState({
city: e.target.value
});
},
handleLgaChange(e) {
this.setState({
lga: e.target.value
});
},
handleUrlChange(e) {
this.setState({
url: e.target.value
});
},
handleDescriptionChange(e) {
this.setState({
description: e.target.value
});
},
handleCatChange(e) {
this.setState({
obj: e.target.value
});
},
handleSubmit(e) {
e.preventDefault();
this.props.onSubmit(this.state);
},
handleChange = (selectedOption) => {
// this.setState({ selectedOption }); add it to state
console.log(`Option selected:`, selectedOption);
},
render() {
return (
<form
name="categories_post"
className="form-horizontal"
onSubmit={this.handleSubmit}
>
<div id="business_post">
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="customerName"
>
Customer Name
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.customerName}
onChange={this.handleCustomerChange}
id="customerName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="email">
Email
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.email}
onChange={this.handleEmailChange}
id="email"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="businessName"
>
Business Name
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.businessName}
onChange={this.handleBusinessChange}
id="businessName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="address"
>
Address
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.address}
onChange={this.handleAddressChange}
id="address"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="city">
City
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.city}
onChange={this.handleCityChange}
id="city"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="lga">
LGA
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.lga}
onChange={this.handleLgaChange}
id="lga"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="url">
URL
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.url}
onChange={this.handleUrlChange}
id="url"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="description"
>
Description
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.description}
onChange={this.handleDescriptionChange}
id="description"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="email">
categories name
</label>
<div className="drop-down">
<Select
value={selectedOption}
onChange={this.handleChange}
options={this.state.obj}
/>
</div>
</div>
<div className="form-group">
<div className="col-sm-2" />
<div className="col-sm-10">
<button
type="submit"
id="categoriesSubmit"
className="btn btn-default"
>
submit
</button>
</div>
</div>
<div className="form-group">
<div className="col-sm-2" />
<div className="col-sm-10">
<button className="btn btn-danger .mt-3">
<Link to="/business">Home</Link>
</button>
</div>
</div>
</div>
</form>
);
}
});
export default Form2;
react-select docs
I've solved it
//handlecatchange
handleCatChange() {
var value = ReactDOM.findDOMNode(this.refs.categoryId).value;
this.setState({
categoryId: parseInt(value)
});
},
the dropdown list
<div className="drop-down">
{/* <Select value={selectedOption} onChange={this.handleChange} options={this.state.obj}></Select> */}
<select ref="categoryId" onChange={this.handleCatChange}>
{this.state.obj.map(obj => {
return (
<option
key={obj.id}
value={obj.id}
onChange={this.handleCatChange}
>
{obj.categoryName}
</option>
);
})}
</select>
</div>

Why won't a React form register inputs on only 3 fields?

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 };

Resources