My code has got 3 input fields i.e first name, last name, email and 1 useState to hold its value, I want to remove the div part containing all the input fields after i hit Sign up and display only Thank You
My code has got 3 input fields i.e first name, last name, email and 1 useState to hold its value, I want to remove the div part containing all the input fields after i hit Sign up and display only Thank You
Before signing up
AFter signing up
const Home = () => {
const [saveInput, setInput] = useState({
fname: '',
lname: '',
email: '',
});
const [message, setMessage] = useState('enter email');
const inputFields = (event) => {
const { value, name } = event.target;
setInput((preValue) => ({
...preValue,
[name]: value,
}));
};
const onSubmits = (event) => {
setMessage('thanks');
};
return (
<div className="homeMain">
<div className="row">
<img
className="home_img"
src="https://i.pinimg.com/originals/53/b5/d7/53b5d70023efa05ec6797b25df413b73.jpg"
/>
<h1 className="home_h1 text-center">Maryam's Restaurant</h1>
<Link
style={{
color: 'white',
textDecoration: 'inherit',
textAlign: 'center',
}}
to="/Restaurant"
className="home_button"
>
View Menu
</Link>
<h2 className="home_h2 text-center">
Binging with Babish is a cooking show dedicated to discovering what
the delectable (and occasionally horrible) foods from fiction actually
taste like.
</h2>
{receipeList.map((curElem) => (
<div className="home2Main">
<img className="home_img2" src={curElem.img} />
<p className="home2Mainp1">{curElem.h1}</p>
<p className="home2Mainp2">{curElem.date}</p>
</div>
))}
</div>
<homeMainDetails />
<div className="home4Main">
<h4>
<bold>Subscribe</bold>
<br />
<small>
Sign up with your email address to receive news and updates.
</small>
</h4>
<input
className="home4MainInput"
name="fname"
onChange={inputFields}
value={saveInput.fname}
type="text"
placeholder="First Name"
/>
<input
className="home4MainInput"
name="lname"
onChange={inputFields}
value={saveInput.lname}
type="text"
placeholder="Last Name"
/>
<input
className="home4MainInput"
name="email"
onChange={inputFields}
value={saveInput.email}
type="text"
placeholder="Email Address"
/>
<button onClick={onSubmits}>Sign Up</button>
<h4 className="home4Mainh4">
<small>{message}</small>
</h4>
</div>
</div>
);
};
export default Home;
You could use another state to indicate your submit state.
This way you can hold state value without affecting to the message state:
Use another state:
const [isSubmited, setIsSubmited] = useState(false);
Change that state when you submit:
const onSubmits = (event) => {
setMessage('thanks');
setIsSubmited(true);
};
Then render it conditionally:
{isSubmited ? (
<div className="home4Main">
...
</div>
) : message}
You can do it with a basic condition message !== "Thank you" like this:
<div className="home4Main">
{message !== "Thank you" && (
<>
<h4>
<bold>Subscribe</bold>
<br />
<small>Sign up with your email address to receive news and updates.</small>
</h4>
<input
className="home4MainInput"
name="fname"
onChange={inputFields}
value={saveInput.fname}
type="text"
placeholder="First Name"
/>
<input
className="home4MainInput"
name="lname"
onChange={inputFields}
value={saveInput.lname}
type="text"
placeholder="Last Name"
/>
<input
className="home4MainInput"
name="email"
onChange={inputFields}
value={saveInput.email}
type="text"
placeholder="Email Address"
/>
<button onClick={onSubmits}>Sign Up</button>
</>
)}
<h4 className="home4Mainh4">
<small>{message}</small>
</h4>
</div>
And update message
const onSubmits = (event) => {
setMessage('Thank you');
};
Create a useState that contains the value on the state of the form.
const [isSubmited, setIsSubmited] = useState(false);
Then use this value in the JSX to conditional render the elements you want to display.
isSubmitted ? <div> Thank You! </div> : <div> your form.... </div>
You can call setIsSubmited(true) when you submit the form.
Related
I am having an issue when I submit my form it puts all of the form data into my URL instead of sending it to my backend. I'm not sure what the issue is at first I thought it was because I didn't have a method="post" in the form tag but that didn't fix my issue because it tried to send the form data to localhost:3000/register instead of localhost:5000/register. Any help would be appreciated.
Bellow is my current Frontend code.
import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom'
import '../css/register.css';
import {IoMdArrowRoundBack} from 'react-icons/io'
import { useState } from 'react'
import axios, { Axios } from 'axios';
const Register = () => {
const [emailReg, setEmailReg] = useState("");
const [usernameReg, setUsernameReg] = useState("");
const [passwordReg, setPasswordReg] = useState("");
const register = () => {
Axios.post('http://localhost:5000/register', {
email: emailReg,
username: usernameReg,
password: passwordReg,
}).catch(function (error) {
console.log(error);
});
};
return (
<div className='background-image'>
<div className='back-button'>
<Link to='/'>
<IoMdArrowRoundBack id='back-arrow' />
<h3>Home</h3>
</Link>
</div>
<div className="container-wrapper">
<div className="container">
<h1>Create Account</h1>
<div className="wrapper">
<form>
<div className="textarea" id="email">
<input
type="email"
onChange={(e) => {
setEmailReg(e.target.value);
}}
name="email"
id="authentactor-email"
placeholder="Email"
defaultValue=""
required
/>
</div>
<div className="textarea" id="username">
<input
type="text"
onChange={(e) => {
setUsernameReg(e.target.value);
}}
name="name"
id="authentactor-text"
placeholder="Username"
defaultValue=""
required
/>
</div>
<div className="textarea" id="password">
<input
type="password"
onChange={(e) => {
setPasswordReg(e.target.value);
}}
name="password"
id="authentactor-password"
placeholder="Password"
defaultValue=""
required
/>
</div>
<div id="button-wrapper">
<button id="button" onClick={register}>Create Account</button>
</div>
</form>
<div className='bottom-text-wrapper'>
<h4>Already have an account? <Link to='/login'>Login Here</Link></h4>
</div>
</div>
</div>
</div>
</div>
)
}
export default Register
According to HTML Living Standard
The missing value default and invalid value default are the Submit Button state.
You can find more information on this question but basically adding type="button" to your Create Account button should do the job.
(so something like <button id="button" type="button" onClick={register}>Create Account</button>)
I figured it out for some reason I can't have the "name" tag in my input fields like it is below.
<div className="textarea" id="password">
<input
type="password"
onChange={(e) => {
setPasswordReg(e.target.value);
}}
name="password"
id="authentactor-password"
placeholder="Password"
defaultValue=""
required
/>
</div>
<div id="button-wrapper">
<button onClick={register} id="button">Create Account</button>
</div>
As soon as I removed the "name" tags I was able to POST my form to the backend and I only get a question mark in my url now instead of all the form data. To fix the question mark I had to set button type="button".
correct code below.
<div className="textarea" id="password">
<input
type="password"
onChange={(e) => {
setPasswordReg(e.target.value);
}}
id="authentactor-password"
placeholder="Password"
defaultValue=""
required
/>
</div>
<div id="button-wrapper">
<button type="button" onClick={register} id="button">Create Account</button>
</div>
I have this project I am working on. The form was working before I added React reCAPTCHA but now, the form is not submitting and reCAPTCHA keeps showing the error message after being checked and submit button is clicked on.
Here is the code:
const validationSchema = yup.object().shape({
name: yup.string().required('Your name is required.'),
email: yup.string().email('Please enter a valid email address.').required('Email is required'),
comment: yup.string().required('No comment entered yet.'),
recaptcha: yup.string().required('Confirm that you are human.'),
});
const {
'article-comment-name': name,
'article-comment-email': email,
'article-comment-comment': commentInput,
'article-comment-submit': submit,
} = keyBy(commentForm?.form?.inputs, KEY);
return (
<div>
<p className="text text-success text-center">{msg && <p>Your comment has been added.</p>}</p>
<Formik
initialValues={formInitialValues}
onSubmit={(comment, { resetForm }) => {
handleVerify();
submitComment(comment);
resetForm();
commentCreated();
}}
validationSchema={validationSchema}
>
{({ values: comment, handleChange, handleSubmit, errors, touched }) => (
<form id="add-comment" className="add-comment" onSubmit={handleSubmit}>
<fieldset>
<div className="row">
<div className="col-md-6">
<label>
{name.label}:{' '}
<span className="text-danger">
{errors.name && touched.name && errors.name}
</span>
</label>
<input type="text" name="name" value={comment.name} onChange={handleChange} />
</div>
<div className="col-md-6">
<label>
{email.label}:{' '}
<span className="text-danger">
{errors.email && touched.email && errors.email}
</span>
</label>
<input type="text" name="email" value={comment.email} onChange={handleChange} />
</div>
</div>
<div>
<label>
{commentInput.label}:{' '}
<span className="text-danger">
{errors.comment && touched.comment && errors.comment}
</span>
</label>
<textarea
name="comment"
cols={40}
rows={3}
value={comment.comment}
onChange={handleChange}
></textarea>
</div>
<Recaptcha
sitekey="mysitekey"
verifyCallback={handleVerify}
render="explicit"
/>
<span className="text-danger">{verify && touched.recaptcha && errors.recaptcha}</span>
</fieldset>
<br />
<button type="submit" className="theme-btn">
<span>{submit.label}</span>
</button>
<div className="clearfix"></div>
</form>
)}
</Formik>
</div>
I have checked the callback and It's working fine on that end. The main problem is that the form is not submitting. It keeps showing this message as stated: Confirm that you are human.
What could be the issue?
In Formik setting the values or errors are all binded with the name prop. The name prop of an element should match with one of the keys with the values . You have validationSchema for recaptcha but it is not associated with your Recaptcha component.
<Recaptcha
sitekey="mysitekey"
verifyCallback={handleVerify}
render="explicit"
/>
Submission in formik triggers a series of events . Please read this Formik Form Submission
I am trying to create a form where the user can edit the information of a contact from a database and then save those changes. The form correctly loads and saves the information from the database, but when componentDidMount() loads the current information into the form fields, the fields don't re-render, causing both the template text (ie. Name, Email, etc) and the information loaded from the database to display on top of each other. Clicking any of the input fields causes the field that was clicked to render properly with the text displaying above the input field, rather than over the loaded text.
How can I force the form to rerender each field after the data has been loaded properly in componentDidMount()? I've tried forceUpdate() but it didn't work, and I haven't been able to find anyone else with this issue. I suspect it has something to do with me using the bootstrap styles wrong, but even after reading all of bootstrap's documentation I couldn't find anything related to my issue.
Here are a couple of screenshots to show the issue.
The form right after loading
The form after clicking the 'Name' field
Here's the relevant code for the component.
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
role: "",
phone: "",
errors: {}
}
}
// Initializer: Copy contact's current data to state
componentDidMount() {
axios.get("/api/contacts/get/" + this.props.match.params.id)
.then(res => {
this.setState({ name: res.data.name });
this.setState({ email: res.data.email });
this.setState({ role: res.data.role });
this.setState({ phone: res.data.phone });
})
.catch(err => console.log(err));
this.forceUpdate();
}
// Change handler: Modify values when changed
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
}
// Submit handler: Save changes to database
onSubmit = e => {
e.preventDefault();
const contact = {
name: this.state.name,
email: this.state.email,
role: this.state.role,
phone: stripNumber(this.state.phone)
};
// Post modified contact to database, then navigate back to Manage Contacts Dashboard
axios.post("/api/admin/contacts/update/" + this.props.match.params.id, contact);
window.location = PREVIOUS_URL;
}
render() {
const { errors } = this.state;
return (
<div>
<Link to={PREVIOUS_URL} className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to Manage Contacts
</Link>
<h3>Edit contact</h3>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.name}
error={errors.name}
id="name"
type="text"
className={classnames("", { invalid: errors.name })}
/>
<label htmlFor="name">Name</label>
<span className="red-text">{errors.name}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", { invalid: errors.email || errors.emailnotfound })}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}{errors.emailnotfound}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.role}
error={errors.role}
id="role"
type="text"
className={classnames("", { invalid: errors.role })}
/>
<label htmlFor="role">Role</label>
<span className="red-text">{errors.role}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.phone}
error={errors.phone}
id="phone"
type="tel"
className={classnames("", { invalid: errors.phone })}
/>
<label htmlFor="phone">Phone Number</label>
<span className="red-text">{errors.phone}</span>
</div>
<div className="form-group">
<input type="submit" value="Submit changes" className="btn btn-primary" />
<Link to={PREVIOUS_URL} className="btn btn-danger"> Cancel </Link>
</div>
</form>
</div>
)
}
}
Have you tried doing the data fetch inside componentWillMount()?
I Am populating values of my input field from JSON data what am getting from back-end, now there is an edit button on UI by on click on that button I am enabling my input field but not able to type inside as I am setting some value
I want to write inside the input once I have made them editable.
const { register, handleSubmit, errors } = useForm();
const [disabled, setdisabled] = useState(false);
const [editBtn, seteditBtn] = useState(true);
<form onSubmit={handleSubmit(onSubmit)}>
{editBtn === true && (
<div align="right">
<button
className="btn white_color_btn"
type="button"
onClick={edit}
>
Edit
</button>
</div>
)}
{editBtn === false && (
<button className="btn white_color_btn" type="submit">
Save
</button>
)}
<div className="row">
<div className="form-group col-6 col-sm-6 col-md-6 col-lg-4 col-xl-4">
<input
type="text"
disable
id="firstName"
name="firstName"
value={dataItems.firstname}
disabled={disabled ? "" : "disabled"}
ref={register({ required: true })}
/>
{errors.firstname && (
<span className="text-danger">first name required</span>
)}
<br />
<label htmlFor="emp_designation">First name</label>
</div>
<div className="form-group col-6 col-sm-6 col-md-6 col-lg-4 col-xl-4">
<input
type="text"
disabled
id="lastname"
name="lastname"
value={dataItems.lastname}
disabled={disabled ? "" : "disabled"}
ref={register({ required: true })}
/>
{errors.lastname && (
<span className="text-danger">last name required</span>
)}
<br />
<label htmlFor="lastname">Lastname</label>
</div>
</div>
</form>
On click of edit
const edit = () => {
setdisabled(true);
};
Code sandbox
You need to make your input as a controlled component and write onChange handlers which will update the state. This will allow you to edit the input field values. Demo
const [disabled, setdisabled] = useState(false);
const [name, setName] = useState(empData.item.name) // setting default name
const [lastname, setLastname] = useState(empData.item.lastname) // default lastname
const edit = () => {
setdisabled(true);
};
return (<div className="container-fluid">
<div align="right">
<button className="btn" onClick={edit}>
Edit
</button>
</div>
<div className="row">
<div>
<input
type="text"
disable
id="item.value"
value={name}
onChange={(e) => {
setName(e.target.value)
}}
disabled={disabled ? "" : "disabled"}
/>
<br />
<label htmlFor="name">Name</label>
</div>
<div>
<input
type="text"
disabled
id={"lastname"}
value={lastname}
onChange={(e) => {
setLastname(e.target.value)
}}
disabled={disabled ? "" : "disabled"}
/>
<br />
<label htmlFor="lastname">Lastname</label>
</div>
</div>
</div>);
Your input is controlled by the value you are giving to it. ie: Its value is always for example empData.item.name.
And you are not providing a change handler to handle the change.
Try adding something like this:
function myChangeHandler(e){
setEditedValueSomeHow(e.target.value);
}
<input
// ...
onChange={myChangeHandler}
/>
Read more about uncontrolled components
PS: you should have had a warning message in your console like this one:
Edit:
You are using react-hook-form to manage your form but at the same time giving values to your inputs.
Please refer to this link to initialize your form values.
short story:
Remove value form your input.
Pass an object to useForm hook containing initial values.
const { register, handleSubmit, errors } = useForm({
defaultValues: {
firstName: "steve",
lastname: "smith"
}
});
Here is a working fork for your codesandbox
In order to make the input editable, you need to update a local state which controlls the input value. As suggested by you in the comments, you are using graphql to get the data, you can make use of useEffect to set the data in state and then on click of edit, update the localState
export default function App() {
const { register, handleSubmit, errors } = useForm();
const [disabled, setdisabled] = useState(true);
const [editBtn, seteditBtn] = useState(true);
const { loading, data } = useQuery("some qraphql query here"); // getting data from graphql
const [formData, setFormData] = useState({});
useEffect(() => {
setFormData(data);
}, [data]);
const edit = () => {
setdisabled(false);
seteditBtn(false);
};
const onSubmit = () => {
console.log(formData);
// submit data using formData state.
};
const handleChange = e => {
const name = e.target.name;
const value = e.target.value;
console.log(name, value);
setFormData(prev => ({ ...prev, [name]: value }));
};
return (
<div className="container-fluid">
<form onSubmit={handleSubmit(onSubmit)}>
{editBtn === true && (
<div align="right">
<button
className="btn white_color_btn"
type="button"
onClick={edit}
>
Edit
</button>
</div>
)}
{editBtn === false && (
<button className="btn white_color_btn" type="submit">
Save
</button>
)}
<div className="row">
<div className="form-group col-6 col-sm-6 col-md-6 col-lg-4 col-xl-4">
<input
type="text"
id="firstname"
name="firstname"
onChange={handleChange}
value={formData.firstname}
disabled={disabled}
ref={register({ required: true })}
/>
{errors.firstname && (
<span className="text-danger">first name required</span>
)}
<br />
<label htmlFor="emp_designation">First name</label>
</div>
<div className="form-group col-6 col-sm-6 col-md-6 col-lg-4 col-xl-4">
<input
type="text"
id="lastname"
name="lastname"
value={formData.lastname}
onChange={handleChange}
disabled={disabled}
ref={register({ required: true })}
/>
{errors.lastname && (
<span className="text-danger">last name required</span>
)}
<br />
<label htmlFor="lastname">Lastname</label>
</div>
</div>
</form>
</div>
);
}
Working mock demo
Hi I am learning Reactjs, redux, and I want to simply print to console.log the username and password for this form.
I have tried console.log(e.target.user.value) but I a getting no results.
here is the handle function.
and then the Form and 2 fields.
how can I print the value of username and password in the handleSubmit function ?
Try Below Code:
handleSubmit = values => {
console.log('values',values);
//Here you will get values in values.username & values.password
}
render(){
const { handleSubmit } = this.props;
return(
<form onSubmit={handleSubmit(this.handleSubmit)}>
<div className="form-inputs">
<Field type="text" label="Name" name="username" data-fieldname="username"
component={bootstrapFormField} placeholder="Username" />
<Field type="password" label="Password" name="password" data-
fieldname="password" component={bootstrapFormField}
placeholder="Password" />
</div>
<div className="form-actions text-right">
<button type="submit" className="btn btn-submit green">
Sign In
</button>
</div>
</form>
)
}