Multiple logically separated radio buttons in the same ReactJS form - reactjs

I am trying to build a very simple form structured with (ideally) a set of radio buttons, a set of checkbox and then another set of radio buttons. These are three different sections of the form I am trying to build.
I would like to keep the current form but I want the two set of radio buttons to be completely independent. First I am not sure they are with the current structure of the code. Second, for some reason, I can pick one option in the first set of radio buttons but the second set seems to be disabled (I can't pick neither long-running nor event-driven).
How can I achieve that? Thanks.
import React, { Component } from "react";
class App extends Component {
constructor() {
super();
this.state = {
customer: "individualDev",
programmingmodel: "long-running",
isWebService: false,
isBatchJob: false,
isAiMl: false,
isDatabase: false,
isWorker: false,
};
}
onValChange = (event) => {
this.setState({
customer: event.target.value,
});
};
onCheckValChange = (e) => {
this.setState({ [e.target.name]: e.target.checked });
};
onSubmitForm = (event) => {
event.preventDefault();
console.log("state", this.state);
};
render() {
return (
<div className="App">
<form onSubmit={this.onSubmitForm}>
<br/>
<b> Customer segment </b>
<br/>
<br/>
<label>
<input
type="radio"
value="IndividualDev"
checked={this.state.customer === "IndividualDev"}
onChange={this.onValChange}
/>
<span>Individual Dev </span>
</label>
<label>
<input
type="radio"
value="Startup"
checked={this.state.customer === "Startup"}
onChange={this.onValChange}
/>
<span>Startup </span>
</label>
<label>
<input
type="radio"
value="smallBusiness"
checked={this.state.customer === "smallBusiness"}
onChange={this.onValChange}
/>
<span>Small Business </span>
</label>
<label>
<input
type="radio"
value="mediumBusiness"
checked={this.state.customer === "mediumBusiness"}
onChange={this.onValChange}
/>
<span>Medium Business </span>
</label>
<label>
<input
type="radio"
value="enterpriseIt"
checked={this.state.customer === "enterpriseIt"}
onChange={this.onValChange}
/>
<span>Enterprise IT </span>
</label>
<label>
<input
type="radio"
value="enterpriseLob"
checked={this.state.customer === "enterpriseLob"}
onChange={this.onValChange}
/>
<span>Enterprise LOB </span>
</label>
<br/>
<br/>
<br/>
<b> Workload </b>
<br/>
<br/>
<label>
<input
type="checkbox"
name="isWebService"
checked={this.state.isWebService}
onChange={this.onCheckValChange}
/>
<span>Web Service </span>
</label>
<label>
<input
type="checkbox"
name="isBatchJob"
checked={this.state.isBatchJob}
onChange={this.onCheckValChange}
/>
<span>Batch Job </span>
</label>
<label>
<input
type="checkbox"
name="isWorker"
checked={this.state.isWorker}
onChange={this.onCheckValChange}
/>
<span>Worker </span>
</label>
<label>
<input
type="checkbox"
name="isAiMl"
checked={this.state.isAiMl}
onChange={this.onCheckValChange}
/>
<span>AI/ML </span>
</label>
<label>
<input
type="checkbox"
name="isDatabase"
checked={this.state.isDatabase}
onChange={this.onCheckValChange}
/>
<span>Database </span>
</label>
<br/>
<br/>
<br/>
<b> Programming model </b>
<br/>
<br/>
<label>
<input
type="radio"
name="long-running"
checked={this.state.programmingmodel === 'long-running'}
onChange={this.onValChange}
/>
<span>Long-running </span>
</label>
<label>
<input
type="radio"
name="event-driven"
checked={this.state.programmingmodel === 'event-driven'}
onChange={this.onValChange}
/>
<span>Event-driven </span>
</label>
<br/>
<br/>
<br/>
<br/>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
export default App;

You should use the same logic that you have already implemented in the checkboxes. Set a name attribute to the radio button and set your state by the [event.target.name]: event.target.value method. Like so:
import React, { Component } from "react";
class App extends Component {
constructor() {
super();
this.state = {
customer: "individualDev",
programmingmodel: "long-running",
isWebService: false,
isBatchJob: false,
isAiMl: false,
isDatabase: false,
isWorker: false,
};
}
onValChange = (event) => {
this.setState({
[event.target.name]: event.target.value,
});
};
onCheckValChange = (e) => {
this.setState({ [e.target.name]: e.target.checked });
};
onSubmitForm = (event) => {
event.preventDefault();
console.log("state", this.state);
};
render() {
return (
<div className="App">
<form onSubmit={this.onSubmitForm}>
<br/>
<b> Customer segment </b>
<br/>
<br/>
<label>
<input
type="radio"
value="IndividualDev"
name="customer"
checked={this.state.customer === "IndividualDev"}
onChange={this.onValChange}
/>
<span>Individual Dev </span>
</label>
<label>
<input
type="radio"
value="Startup"
name="customer"
checked={this.state.customer === "Startup"}
onChange={this.onValChange}
/>
<span>Startup </span>
</label>
<label>
<input
type="radio"
value="smallBusiness"
name="customer"
checked={this.state.customer === "smallBusiness"}
onChange={this.onValChange}
/>
<span>Small Business </span>
</label>
<label>
<input
type="radio"
value="mediumBusiness"
name="customer"
checked={this.state.customer === "mediumBusiness"}
onChange={this.onValChange}
/>
<span>Medium Business </span>
</label>
<label>
<input
type="radio"
value="enterpriseIt"
name="customer"
checked={this.state.customer === "enterpriseIt"}
onChange={this.onValChange}
/>
<span>Enterprise IT </span>
</label>
<label>
<input
type="radio"
value="enterpriseLob"
name="customer"
checked={this.state.customer === "enterpriseLob"}
onChange={this.onValChange}
/>
<span>Enterprise LOB </span>
</label>
<br/>
<br/>
<br/>
<b> Workload </b>
<br/>
<br/>
<label>
<input
type="checkbox"
name="isWebService"
checked={this.state.isWebService}
onChange={this.onCheckValChange}
/>
<span>Web Service </span>
</label>
<label>
<input
type="checkbox"
name="isBatchJob"
checked={this.state.isBatchJob}
onChange={this.onCheckValChange}
/>
<span>Batch Job </span>
</label>
<label>
<input
type="checkbox"
name="isWorker"
checked={this.state.isWorker}
onChange={this.onCheckValChange}
/>
<span>Worker </span>
</label>
<label>
<input
type="checkbox"
name="isAiMl"
checked={this.state.isAiMl}
onChange={this.onCheckValChange}
/>
<span>AI/ML </span>
</label>
<label>
<input
type="checkbox"
name="isDatabase"
checked={this.state.isDatabase}
onChange={this.onCheckValChange}
/>
<span>Database </span>
</label>
<br/>
<br/>
<br/>
<b> Programming model </b>
<br/>
<br/>
<label>
<input
type="radio"
name="programmingmodel"
value="long-running"
checked={this.state.programmingmodel === 'long-running'}
onChange={this.onValChange}
/>
<span>Long-running </span>
</label>
<label>
<input
type="radio"
name="programmingmodel"
value="event-driven"
checked={this.state.programmingmodel === 'event-driven'}
onChange={this.onValChange}
/>
<span>Event-driven </span>
</label>
<br/>
<br/>
<br/>
<br/>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
export default App;

Related

How save input values and checked information in state?

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

react hook form: how can i validate a group of radio buttons or checkboxes to ensure at least one is selected

I have a group of checkboxes and a group if radios and I want to validate with react hook form to ensure that an error message is generated if none have been selected on submit.
I have tried experimenting with the form builder on their website but I cant work out how to validate a group of items as a single unit of validation.
<div>
<span>Option A <input type="checkbox" value="A" /></span>
<span>Option B <input type="checkbox" value="B" /></span>
<span>Option C <input type="checkbox" value="C" /></span>
</div>
<...output a validation error if one or more checkboxes hasnt been checked within the group>
<div>
<span>Option A <input type="radio" value="A" /></span>
<span>Option B <input type="radio" value="B" /></span>
<span>Option C <input type="radio" value="C" /></span>
</div>
<...output a validation error if one or more radios hasnt been checked within the group>
Is this possible and is there a correct way to do it?
Thank you for your time and attention.
You added the react-hook-form tag to your question but there is nothing in your code related to it. If indeed you're using React Hook Form a way to accomplish what you want is using schema validation through yup:
const schema = yup.object().shape({
checkbox: yup.array().min(1),
radio: yup.string().required(),
});
export default function App() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
});
const onSubmit = (data) => {
alert(JSON.stringify(data));
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<span>
Checkbox 1
<input type="checkbox" {...register('checkbox')} value="A" />
</span>
<span>
Checkbox 1
<input type="checkbox" {...register('checkbox')} value="B" />
</span>
<span>
Checkbox 3
<input type="checkbox" {...register('checkbox')} value="C" />
</span>
<p style={{ color: 'red' }}>
{errors.checkbox && 'At least one checkobox must be selected'}
</p>
<span>
<label>Radio 1</label>
<input type="radio" {...register('radio')} value="A" />
</span>
<span>
<label>Radio 2</label>
<input type="radio" {...register('radio')} value="B" />
</span>
<span>
<label>Radio 3</label>
<input type="radio" {...register('radio')} value="C" />
</span>
<p style={{ color: 'red' }}>{errors.radio && 'Radio is required'}</p>
<input type="submit" />
</form>
);
}
See a working stackblitz.
Note that as radio button options are exclusive (only one can be selected) you're just sayng that the field is required.
Check out this guide and the documentation for radio buttons
In short, giving the same name attribute to your radio buttons ensures that only one of them can be selected at a time. Adding an onChange function linked to a useState within your component allows you to track the selected value and react if none has been selected.
The resulting code should be something like this:
const YourComponent = () => {
const [myValue, setMyValue] = useState(null);
const onValueChange = e => {
setMyValue(e.target.value);
};
return (
<div>
<div onChange={onValueChange}>
<span>
Option A <input type="checkbox" value="A" name="myValue" />
</span>
<span>
Option B <input type="checkbox" value="B" name="myValue" />
</span>
<span>
Option C <input type="checkbox" value="C" name="myValue" />
</span>
</div>
{!myValue && <span>Please select a value</span>}
</div>
);
};

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

Im only getting the username and password field? React

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.

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

Resources