Getting the value of list of inputs in react - reactjs

I have list of input tags in my react app. I want to get the value of all inputs when I click on submit button.
I can get the value of one input, but not able to get all the values in one go.
keys.map(i => <Input fullWidth defaultValue={i} />)
<Button>Submit</Button>
get the list of values

Sample application for multiple inputs
const App = () => {
const [people, setPeople] = React.useState([
{ firstName: "Herry", lastName: "Sejal" },
{ firstName: "John", lastName: "Siri" },
{ firstName: "Bukky", lastName: "Sera" }
]);
const [person, setPerson] = React.useState({ firstName: "", lastName: "" });
const onChange = e => {
setPerson({ ...person, [e.target.name]: e.target.value });
};
const onSubmit = e => {
e.preventDefault();
const newVal = [...people, person];
setPeople(newVal);
setPerson({ firstName: "", lastName: "" });
};
return (
<div className="container">
<div className="row">
<div className="col">
<h2>Add a person: </h2>
<hr />
<form onSubmit={onSubmit}>
<div className="form-group">
<input
type="text"
className="form-control"
name="firstName"
placeholder="First Name.."
value={person.firstName}
onChange={onChange}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control"
name="lastName"
placeholder="Last Name.."
value={person.lastName}
onChange={onChange}
/>
</div>
<button className="btn btn-success" type="submit">
Add person
</button>
</form>
</div>
<div className="col">
<h2>People: </h2>
<hr />
{people.map(p => (
<div key={Math.random() * 1000000000}>
<p>
{p.firstName} {p.lastName}
</p>
</div>
))}
</div>
</div>
</div>
);
};

Related

Diffrent Input type using Bootstrap desing in Redux-React functional componnent

Im trying to display my data in diffrent Form inputs, but in some of them, i dont know how to reach my data.
//DashShowDetails.js:
import { useState, useEffect } from 'react';
import { Button, Form } from 'react-bootstrap';
import { Input, Label } from 'reactstrap';
function DashShowDetails(props) {
const { data } = props;
const [edit, setEdit] = useState(false);
const [formData, setFormData] = useState({
id: data._id,
showId: data.showId,
showName: data.name,
showGenres: data.genres,
showStatus: data.status,
showPremiered: data.premiered,
showEnded: data.ended,
showRating: data.rating,
showSummery: data.summary,
showImage: data.image,
});
const onClick = () => {
setEdit(current => !current)
}
const onChange = (e) => {
setFormData((prevState) => ({
...prevState,
[e.target.name]: e.target.value
}))
}
const onSubmit = async (e) => {
e.preventDefault()
let show = formData;
dispatch(updateDashShow(show));
setEdit(current => !current);
setFormData((prevState) => ({
...prevState,
}))
}
useEffect(() => {
}, [edit]);
return (
<div>
<div>
<h5>{data.name}</h5>
<Button onClick={onClick}>Edit Show</Button>
</div>
<div>
{edit === true && (
<div>
<h3>Edit {data.name}</h3>
<Form onSubmit={onSubmit} >
<div>
<Label>Show ID:</Label>
<Input type="text" name="showId" value={data.showId} onChange={onChange} />
</div>
<div>
<Label>Show Name:</Label>
<Input type="text" name="showName" defaultValue={data.name} onChange={onChange} />
</div>
<div>
<Label>Show Genres:</Label>
<Input type="text" name="showGenres" defaultValue={data.genres} onChange={onChange} />
</div>
<div>
<Label>Show Status:</Label>
<Input type="select" name="showStatus" select={data.status} onChange={onChange}>
<option value="running">Running</option>
<option value="ended">Ended</option>
</Input>
</div>
<div>
<Label>Premiered Date:</Label>
<Input type="date" name="showPremiered" value={data.premiered} onChange={onChange} />
</div>
<div>
<Label>Ended Date:</Label>
<Input type="date" name="showEnded" value={data.ended} onChange={onChange} />
</div>
<div>
<Label>Show Rating:</Label>
<Input type="array" name="showRating" value={data.rating} onChange={onChange} />
</div>
<div>
<Label>Show Summery:</Label>
<Input type="textarea" name="showSummery" value={data.summery} onChange={onChange} />
</div>
<div>
<Label>Image:</Label>
</div>
<Button type="submit">Update Show</Button>
<Button>Delete Show</Button>
</Form>
</div>
)}
</div>
</div>
);
}
export default DashShowDetails;
My output when i click 'Edit Show' is:
How can i display my Data in inputs: Premiered Date, Show Rating, Show Summery & Image?
My Schema file in Node.js: (sending new data to MoongoDB)
const showSchema = new mongoose.Schema({
showId: {type: Number},
name: {type: String},
genres: {type: Array},
status: {type: String},//Boolean
premiered: {type: Date},
ended: {type: Date},
rating: {type: Array},
summary: {type: String},
image: {type: Array},//Link?File?
})
module.exports = mongoose.model('shows', showSchema);

Why is my input field not editable even after adding onChange function - react

I am a new learner in react, I tried a simple login form which takes user input and passes it to backend. This application is also written to create tokens if the login credentials are correct. In order to take user input I have added the onChange() function and called it for each input field, however the it is still not editable. I couldn't find the error. I also have added onSubmit() function implementation. I did try various other ways of calling the onChange function, however it wasnt successful.
const [formData, setFormData] = useState({
clientEmail: "",
clientPassword: "",
errorMsg: false,
loadingSpinner: false,
});
// destructure form data
const { clientEmail, clientPassword, errorMsg, loadingSpinner } = formData;
const handleChange = (evt) => {
setFormData({
...formData,
[evt.target.name]: evt.target.value,
errorMsg: "",
});
};
const handleSubmit = (evt) => {
evt.preventDefault();
//form validation
if (isEmpty(clientEmail) || isEmpty(clientPassword)) {
setFormData({
...formData,
errorMsg: "All field are Required",
});
} else if (!isEmail(clientEmail)) {
setFormData({
...formData,
errorMsg: "Invalid Email new",
});
} else {
const { clientEmail, clientPassword} = formData;
const data = {
clientEmail,
clientPassword,
};
setFormData({
...formData,
loadingSpinner: true,
});
ClientLoginUser(data)
.then((response) => {
console.log(response);
setClientAuthentication(response.data.token, response.data.clients);
if (isClientAuthenticated()) {
console.log("client Successful");
history.push("./clientDashboard");
}
})
.catch((err) => {
console.log("client login api controller error: ", err);
setFormData({
...formData,
errorMsg:err.response.data.errorMessage,
loading:false
});
});
}
};
const showLoginForm = () => (
<Fragment>
<div className="card px-5 py-5">
<div className="card-body">
<h5 className="card-title text-center pb-3">Client Login</h5>
<form className="login-form"
onSubmit={handleSubmit}
noValidate>
{/* Email */}
<div className="form-group">
<input
type="email"
className="form-control"
name="email"
value={clientEmail}
placeholder="Email"
onChange={handleChange}
/>
</div>
{/* Password */}
<div className="form-group">
<input
type="password"
className="form-control"
name="password"
value={clientPassword}
placeholder="Password"
onChange={handleChange}
/>
</div>
{/* Submit button */}
<div className="form-group pt-3">
<button
type="submit"
className="btn btn-primary btn-lg btn-block"
>
Login
</button>
</div>
</form>
</div>
</div>
</Fragment>
);
/****************************
* Render
****************************/
return (
<div className="login-container">
<GridWrapper>
<div className="container-fluid">
<div className="row px-4 vh-100">
<div className="col-12 col-md-8 my-auto pl-5">
<img
src="/images/welcomeLogo.png"
className="img-fluid"
alt="Logo"
/>
</div>
<div className="col-12 col-md-3 align-self-center">
{errorMsg && showErrorMsg(errorMsg)}
{loadingSpinner && (
<div className="text-center pb-5">{showLoading()}</div>
)}
{showLoginForm()}
</div>
</div>
</div>
</GridWrapper>
</div>
);
};
// return <p>ClientLogin Component</p>;
The name in input is not exactly the same as in formData state
you got this state
const [formData, setFormData] = useState({
clientEmail: "",
clientPassword: "",
errorMsg: false,
loadingSpinner: false,
});
which contain data like clientEmail
<input
type="email"
className="form-control"
name="email"
value={clientEmail}
placeholder="Email"
onChange={handleChange}
/>
which contains name="email"
in handleChange Function
const handleChange = (evt) => {
setFormData({
...formData,
[evt.target.name]: evt.target.value,
errorMsg: "",
});
};
you contains [evt.target.name]: evt.target.value
thats mean you are trying to assign new Values to formData.email not to formData.clientEmail
there are two solution
first you can change
const [formData, setFormData] = useState({
email: "",
...
});
or you can
<input
type="email"
className="form-control"
name="clientEmail"
value={clientEmail}
placeholder="Email"
onChange={handleChange}
/>

value of the option selected not passing in react

Trying to get a response when clicking and store the selected option from the selected value genre, not sure how to add a select new state variable or a post method. When the option is clicked the click handler is not called with the selected options so that we can add it to the state. My genre is also seen as undefined when I don't click on the the text type.
Feedback.js
import React, { useState } from "react";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.min.css";
import Layout from "./Layout";
const Feedback = () => {
const [values, setValues] = useState({
name: "",
artist: "",
songTitle: "",
email: "",
message: "",
phone: "",
genre: "",
uploadedFiles: [],
buttonText: "Submit",
uploadPhotosButtonText: "Upload files",
});
// destructure state variables
const {
name,
artist,
songTitle,
label,
email,
message,
phone,
genre,
uploadedFiles,
buttonText,
uploadPhotosButtonText,
} = values;
// destructure env variables
const {
REACT_APP_API,
REACT_APP_CLOUDINARY_CLOUD_NAME,
REACT_APP_CLOUDINARY_UPLOAD_SECRET,
} = process.env;
// event handler
const handleChange = (name) => (event) => {
setValues({ ...values, [name]: event.target.value });
};
const handleSubmit = (event) => {
event.preventDefault();
setValues({ ...values, buttonText: "...sending" });
// send to backend for email
console.table({ name, email, phone, message, uploadedFiles, genre });
axios({
method: "POST",
url: `${REACT_APP_API}/feedback`,
data: {
name,
artist,
songTitle,
label,
email,
genre,
phone,
message,
uploadedFiles,
},
})
.then((response) => {
// console.log('feedback submit response', response);
if (response.data.success) toast.success("Thanks for your feedback");
setValues({
...values,
name: "",
artist: "",
songTitle: "",
label: "",
phone: "",
email: "",
genre: "",
message: "",
uploadedFiles: [],
buttonText: "Submitted",
uploadPhotosButtonText: "Uploaded",
});
})
.catch((error) => {
// console.log('feedback submit error', error.response);
if (error.response.data.error) toast.error("Failed! Try again!");
});
};
function onChangeInput(value) {
console.log(value);
}
const uploadWidget = () => {
window.cloudinary.openUploadWidget(
{
cloud_name: REACT_APP_CLOUDINARY_CLOUD_NAME,
upload_preset: REACT_APP_CLOUDINARY_UPLOAD_SECRET,
tags: ["ebooks"],
},
function (error, result) {
// console.log(result);
setValues({
...values,
uploadedFiles: result,
uploadPhotosButtonText: `${
result ? result.length : 0
} Photos uploaded`,
});
}
);
};
const feedbackForm = () => (
<React.Fragment>
<div className="form-group">
<button
onClick={() => uploadWidget()}
className="btn btn-outline-secondary btn-block p-5"
>
{uploadPhotosButtonText}
</button>
</div>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label className="text-muted">Description</label>
<textarea
onChange={handleChange("message")}
type="text"
className="form-control"
value={message}
required
></textarea>
</div>
<div className="form-group">
<label className="text-muted">Your Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("name")}
value={name}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Your Email</label>
<input
className="form-control"
type="email"
onChange={handleChange("email")}
value={email}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Your Phone</label>
<input
className="form-control"
type="number"
onChange={handleChange("phone")}
value={phone}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Artist Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("artist")}
value={artist}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Song Title</label>
<input
className="form-control"
type="text"
onChange={handleChange("songTitle")}
value={songTitle}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Record Label Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("label")}
value={label}
/>
</div>
<div className="form-group">
<label className="text-muted">Music Genre:</label>
<select
className="form-control"
value={genre}
type="select"
onChange={handleChange("genre")}
>
<option value="steak">Steak</option>
<option value="sandwich">Sandwich</option>
<option value="dumpling">Dumpling</option>
</select>
</div>
<button className="btn btn-outline-primary btn-block">
{buttonText}
</button>
</form>
</React.Fragment>
);
return (
<Layout>
<ToastContainer />
<div className="container text-center">
<h1 className="p-5">Feedback Online</h1>
</div>
<div className="container col-md-8 offset-md-2">{feedbackForm()}</div>
<br />
<br />
<br />
</Layout>
);
};
export default Feedback;

How to achieve validation on submit for the first time, then validation on change after the second time using formik

So I am facing a couple of problems when trying to use formik to handle my input fields,
basically after pressing on one input fields validation starts on the rest and I dont want that to happen.
Preferably for the first time validation should only take place onsubmit and then after that validation continues onchange.
Here is my code:
logic:
const CompanyProfile = () => {
const CompanySchema = Yup.object().shape({
name: Yup.string()
.min(2, 'too short')
.required(ERROR_REQUIRED),
industry: Yup.string().notRequired(),
address: Yup.string().notRequired(),
crn: Yup.number().required(ERROR_REQUIRED),
website: Yup.string().notRequired(),
employeesNbr: Yup.string().required(ERROR_REQUIRED),
phoneNumber: Yup.number().required(ERROR_REQUIRED),
userRole: Yup.string().required(ERROR_REQUIRED),
personCheck: Yup.boolean().required(ERROR_REQUIRED),
});
const formik = useFormik({
initialTouched: false,
validateOnChange: true,
initialValues: {
name: '',
industry: '',
address: '',
crn: '',
website: '',
employeesNbr: '',
phoneNumber: '',
userRole: '',
personCheck: false,
},
validationSchema: CompanySchema,
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
});
return (
<Skeleton pageTitle={PAGE_TITLE_COMPANY_PROFILE}>
<CompanyProfileForm formik={formik} />
</Skeleton>
);
};
export default CompanyProfile;
front-end
const CompanyProfileForm = ({ formik }: Props) => {
const [modal, setModal] = useState(false);
const { errors } = formik;
const handleSubmit = () => {
console.log(formik);
formik.handleSubmit();
if (
!formik.errors.name &&
!formik.errors.crn &&
!formik.errors.employeesNbr &&
!formik.errors.phoneNumber &&
!formik.errors.userRole
) {
setModal(true);
} else setModal(false);
};
const handleModalClick = () => {
setModal(false);
};
return (
<div style={screenContainer}>
{formik.errors.personCheck && modal && (
<ModalPopup
warningMessage={WARNING_CONFIRM_PERSON}
onClick={handleModalClick}
success={false}
/>
)}
<div style={inputDiv}>
<div style={inputContainerLabel}>
<Nunito16 style={labelStyle}>{COMPANY_DETAILS}</Nunito16>
</div>
<div style={inputFieldContainer}>
<div style={firstInputColumn}>
<div style={inputContainer}>
<Nunito20 style={inputLabel}>{COMPANY_FORM_INPUT_NAME}</Nunito20>
<InputValidation
type="text"
name="name"
value={formik.name}
handleInputChange={formik.handleChange}
hasError={formik.errors.name}
validationMessage={formik.errors.name}
/>
</div>
<div style={inputContainer}>
<Nunito20 style={inputLabel}>
{COMPANY_FORM_INPUT_INDUSTRY}
</Nunito20>
<InputValidation
type="text"
name="industry"
value={formik.industry}
handleInputChange={formik.handleChange}
hasError={formik.errors.industry}
validationMessage={ERROR_REQUIRED}
/>
</div>
<div style={inputContainer}>
<Nunito20 style={inputLabel}>
{COMPANY_FORM_INPUT_ADDRESS}
</Nunito20>
<InputValidation
type="text"
name="address"
value={formik.address}
handleInputChange={formik.handleChange}
hasError={formik.errors.address}
validationMessage={formik.errors.address}
/>
</div>
<div style={inputContainer}>
<Nunito20 style={inputLabel}>
{COMPANY_FORM_INPUT_CR_NUMBER}
</Nunito20>
<InputValidation
type="number"
name="crn"
value={formik.crn}
handleInputChange={formik.handleChange}
hasError={formik.errors.crn}
validationMessage={formik.errors.crn}
/>
</div>
</div>
<div style={secondInputColumn}>
<div style={inputContainer}>
<Nunito20 style={inputLabel}>
{COMPANY_FORM_INPUT_WEBSITE}
</Nunito20>
<InputValidation
type="url"
name="website"
value={formik.website}
handleInputChange={formik.handleChange}
hasError={formik.errors.website}
validationMessage={formik.errors.website}
/>
</div>
<div style={inputContainer}>
<Nunito20 style={inputLabel}>
{COMPANY_FORM_INPUT_EMPLOYEES_NBR}
</Nunito20>
<InputValidation
type="number"
name="employeesNbr"
value={formik.employeesNbr}
handleInputChange={formik.handleChange}
hasError={formik.errors.employeesNbr}
validationMessage={ERROR_REQUIRED}
/>
</div>
<div style={inputContainer}>
<Nunito20 style={inputLabel}>{COMPANY_FORM_INPUT_PHONE}</Nunito20>
<PhoneInputValidation
name="phoneNumber"
value={formik.phoneNumber}
handleInputChange={formik.handleChange}
hasError={formik.errors.phoneNumber}
validationMessage={formik.errors.phoneNumber}
/>
</div>
<div style={inputContainer}>
<Nunito20 style={inputLabel}>
{COMPANY_FORM_INPUT_EMPLOYEE_ROLE}
</Nunito20>
<InputValidation
type="text"
name="userRole"
value={formik.userRole}
handleInputChange={formik.handleChange}
hasError={formik.errors.userRole}
validationMessage={formik.errors.userRole}
/>
</div>
</div>
</div>
<div style={tickBoxContainer}>
<div style={checkBoxDiv}>
<Checkbox handleChange={formik.handleChange} name="personCheck" />
<NunitoBold18 style={checkBoxLabel}>{PERSON_CHECK}</NunitoBold18>
</div>
</div>
</div>
<SubmitButton style={submitButton} onClick={handleSubmit}>
{CONTINUE}
</SubmitButton>
</div>
);
};
Try
Make use of validateOnChange and validateOnBlur props and issue the value of false.
See docs:
https://jaredpalmer.com/formik/docs/guides/validation#field-level-validation
https://jaredpalmer.com/formik/docs/api/formik#validateonblur-boolean
Any further issues, leave a comment..

Multiples Forms rendering a card

I'm having a lot of troubles trying to render the data I passed into my inputs to render a "contact" card.
I'm handling the inputs, changing the states accordingly, but when it comes to the final state, rendering a "Contact card" with all my data I just don't know how to make it works.
I think the problem is at my "renderCard" method.
If someone could give me a hand I think i'm really close but yet so far..
import React, { Component } from 'react';
export default class Todo extends Component {
state = {
nom: '',
age: '',
ville: '',
items: [],
start: 0
};
onChange = (event) => {
this.setState({
[event.target.name]: event.target.value
});
}
onSubmit = (event) => {
event.preventDefault();
this.setState({
nom: '',
age: '',
ville: '',
items: [...this.state.items, this.state.nom, this.state.age, this.state.ville],
start: 1
});
}
renderCard = () => {
return this.state.items.map((item, index) => {
return (
<div className="card" key={index}>
{item.nom}
{item.age}
{item.ville}
</div>
);
});
}
render() {
return (
<div>
<div className="card mb-3">
<div className="card-header">Ajouter une Personne</div>
<div className="card-body">
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label htmlFor="name">Nom</label>
<input
type="text"
className="form-control form-control-lg"
name="nom"
value={this.state.nom}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label htmlFor="name">Age</label>
<input
type="text"
className="form-control form-control-lg"
name="age"
value={this.state.age}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label htmlFor="name">Ville</label>
<input
type="text"
className="form-control form-control-lg"
name="ville"
value={this.state.ville}
onChange={this.onChange}
/>
</div>
<button className="btn btn-primary btn-block">Créez votre Fiche !</button>
</form>
</div>
</div>
{this.renderCard()}
</div>
);
}
}
You are making mistake in setting the items in state on submit. I hope the items should be a array of objects
Please check the below code
onSubmit = (event) => {
event.preventDefault();
this.setState({
nom: '',
age: '',
ville: '',
items: [...this.state.items, {nom:this.state.nom, age:this.state.age, ville: this.state.ville}],
start: 1
});

Resources