I am trying to put regex input validation in my react project, but getting continuous error i.e Validation is not there and Validation(values) is not there.
TeacherRegistration.js
import React, { useState } from 'react'
import Validation from '../Validation'
const TeacherRegistraion = () => {
const [teacherRegistraion, setTeacherRegistration] = useState({
tFirstName: '',
tLastName: '',
tEmail: '',
})
const [error, setError] = useState({});
const handleInput = (e) => {
const name = e.target.name;
const value = e.target.value;
console.log(name, value);
setTeacherRegistration({ ...teacherRegistraion, [name]: value });
}
const handleSubmit = (e) => {
e.preventDefault();
setError(Validation(values));
const newRecord = { ...teacherRegistraion, id: new Date().getTime().toString() }
console.log(newRecord)
setTeacherRegistration(
{
tFirstName: '',
tLastName: '',
tEmail: '',
}
)
}
return (
<div className='container'>
<div className='title'> Registration</div>
<div className="content">
<form action="" onSubmit={handleSubmit}>
<div className="user-details">
<div className='input-box'>
<span htmlFor="tFirstName">First Name</span>
<input type="text"
name='tFirstName'
value={teacherRegistraion.tFirstName}
onChange={handleInput}
id='tFirstName'
required
/>
{error.tFirstName && <p className='error'>{error.tFirstName}</p>}
</div>
<div className='input-box'>
<span htmlFor="tLastName">Last Name</span>
<input type="text"
name='tLastName'
value={teacherRegistraion.tLastName}
onChange={handleInput}
id='tLastName'
required
/>
{error.tLastName && <p className='error'>{error.tLastName}</p>}
</div>
<div className='input-box'>
<span htmlFor="tEmail">Email</span>
<input type="email"
name='tEmail'
value={teacherRegistraion.tEmail}
onChange={handleInput}
id='tEmail'
required
/>
{error.tEmail && <p className='error'>{error.tEmail}</p>}
</form>
</div>
</div>
)
I am trying to put regex input validation in my react project, but getting continuous error i.e Validation is not there and Validation(values) is not there.
Validation.js
const Validation = (values) => {
let errors = {};
if (!values.tFirstName) {
errors.tFirstName = 'Firstname is required'
}
if (!values.tLasttName) {
errors.tLasttName = 'Lasttname is required'
}
if (!values.tEmail) {
errors.email = 'Email is required'
}
else if (!/\S+#\S+\. \S+/.test(values.tEmail)) {
errors.tEmail = 'Email is invalid'
}
return errors;
}
export default Validation;
I am trying to put regex input validation in my react project, but getting continuous error i.e Validation is not there and Validation(values) is not there.
Related
This is the first web app that im building using react and im completely lost in validating the login and this is the code i follow and im not able to type anything into the field.
The error occurs during validating since previous i used this and works well before i tried to validate.
import React , {Fragment, useState,useEffect} from 'react'
import { useDispatch , useSelector} from 'react-redux'
import {useAlert} from 'react-alert'
import MetaData from '../layouts/MetaData'
import Loader from '../layouts/Loader'
import { Link, useLocation } from 'react-router-dom'
import {userLogin, clearErrors} from '../../actions/users'
import { useNavigate ,useParams} from 'react-router-dom'
const Login = () => {
const dispatch= useDispatch();
const alert=useAlert();
//const [email,setEmail]=useState('');
//const [password,setPassword]=useState('');
const initialValues = { email: "", password: "" };
const [formValues, setFormValues] = useState(initialValues);
const [formErrors, setFormErrors] = useState({});
const [isSubmit, setIsSubmit] = useState(false);
let navigate=useNavigate();
let location =useLocation();
const {isAuthenticated,error,loading}=useSelector(state =>state.auth);
const redirect=location.search ? location.search.split('=')[1] : '/'
useEffect(()=>{
if(isAuthenticated){
navigate(redirect)
}
if(error){
alert.error(error);
dispatch(clearErrors());
}
}, [dispatch, alert, isAuthenticated, error, navigate])
const handleChange = (e) => {
const { name, value } = e.target;
setFormValues({ ...formValues, [name]: value });
};
const loginHandler = (ev) => {
ev.preventDefault()
setFormErrors(validate(formValues));
setIsSubmit(true);
dispatch(userLogin(formValues.email,formValues.password));
}
useEffect(() => {
console.log(formErrors);
if (Object.keys(formErrors).length === 0 && isSubmit) {
console.log(formValues);
}
}, [formErrors]);
const validate = (values) => {
const errors = {};
const regex = /^[^\s#]+#[^\s#]+\.[^\s#]{2,}$/i;
if (!values.username) {
errors.username = "Username is required!";
}
if (!values.email) {
errors.email = "Email is required!";
} else if (!regex.test(values.email)) {
errors.email = "This is not a valid email format!";
}
if (!values.password) {
errors.password = "Password is required";
} else if (values.password.length < 4) {
errors.password = "Password must be more than 4 characters";
} else if (values.password.length > 10) {
errors.password = "Password cannot exceed more than 10 characters";
}
return errors;
};
return (
<Fragment>
{loading ?<Loader></Loader> :(
<Fragment>
<MetaData title={'Login'} />
<div className="row wrapper">
<div className="col-10 col-lg-5">
<form className="shadow-lg" onSubmit={loginHandler}>
<h1 className="mb-3">Login</h1>
<div className="form-group">
<label htmlFor="email_field">Email</label>
<input
type="email"
id="email_field"
className="form-control"
value={formValues.email}
onChange={handleChange}
/>
</div>
<div className="form-group">
<label htmlFor="password_field">Password</label>
<input
type="password"
id="password_field"
className="form-control"
value={formValues.password}
onChange={handleChange}
/>
</div>
<Link to="/password/forgot" className="float-right mb-4">Forgot Password?</Link>
<button
id="login_button"
type="submit"
className="btn btn-block py-3"
>
LOGIN
</button>
<Link to="/register" className="float-right mt-3">New User?</Link>
</form>
</div>
</div>
</Fragment>
)}
</Fragment>
)}
export default Login
Thanks a lot in advance!!
You are missing name prop (attribute) in your JSX.
Due to this your function is failing to update the state with correct values.
const handleChange = (e) => {
const { name, value } = e.target;
// name will be undefined, because you haven't set it.
setFormValues({ ...formValues, [name]: value });
};
Simply Add name and it will work.
<input
type="email"
id="email_field"
name="email"
className="form-control"
value={formValues.email}
onChange={handleChange}
/>
<input
type="password"
id="password_field"
className="form-control"
name="password"
value={formValues.password}
onChange={handleChange}
/>
I'm looking to implement the form validation using react-hook. However, I'm facing some trouble in doing so as I've also added some stuff on my own under the handleSubmit and I'm not really sure how to go about it.
export default function Contact() {
const [message, setMessage] = useState(false);
const [alert, setAlert] = useState(true);
const { register, errors} = useForm();
const [showElement, setShowElement] = React.useState(false);
const handleSubmit = (e) => {
e.preventDefault();
emailjs.sendForm('', '', e.target, '')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
e.target.reset();
setMessage(true);
setShowElement(true);
setTimeout(function () {
setShowElement(false);
}, 4000);
};
const onSubmit= data=>{
console.log(data);
}
return (
<div className="right">
<h2>Contact Me</h2>
<form onSubmit={handleSubmit} id="contactform">
<input type="text" placeholder="Name" name="name" ref={register({required: true, minLength: 2})}
required />
<button type="submit">Send</button>
</form>
{showElement ? (
<div className="submitmsg">
{message && (
<span> Messaged received. I'll respond to your query ASAP! </span>
)}
</div>
) : (
<div> </div>
)}{" "}
</div>
)
}
Thank you!
React hook form provides the handeSubmit method that receives the form data after validations. Also, you must use the errors object to show errors in the UI.
Here is the sandbox link: https://codesandbox.io/s/exciting-dust-df5ft?file=/src/App.js
I have updated your code accordingly:
import { useState } from "react";
import React from "react";
import emailjs from "emailjs-com";
import { useForm } from "react-hook-form";
export default function Contact() {
const [message, setMessage] = useState(false);
const {
register,
handleSubmit,
formState: { errors }
} = useForm();
const [showElement, setShowElement] = React.useState(false);
const onSubmit = (data) => {
emailjs
.send(
"service_t1ccrgq",
"template_gmmcyzr",
data,
"user_d0vUwhmqvbIYhEsyZF8tu"
)
.then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
setMessage(true);
setShowElement(true);
setTimeout(function () {
setShowElement(false);
}, 4000);
};
return (
<div className="contact" id="contact">
<div className="left">
<img className="contactme" src="asset/email.gif" />
</div>
<div className="right">
<h2>Contact Me</h2>
<form onSubmit={handleSubmit(onSubmit)} id="contactform">
<input
type="text"
placeholder="Name"
name="name"
{...register("name", {
required: "Name is Required",
minLength: {
value: 3,
message: "Should be greater than 3 characters"
}
})}
/>
<input
type="tel"
placeholder="Mobile Number"
name="mobile"
{...register("mobile", {
required: "Mobile Number is Required",
minLength: {
value: 3,
message: "Should be greater than 3 characters"
}
})}
/>
<input
type="text"
placeholder="Email"
name="email"
{...register("email", {
required: "Email is Required",
minLength: {
value: 3,
message: "Should be greater than 3 characters"
}
})}
/>
<textarea
placeholder="Message"
required
name="message"
{...register("message", {
required: "Message is Required",
minLength: {
value: 3,
message: "Should be greater than 3 characters"
}
})}
></textarea>
<button type="submit">Send</button>
</form>
{showElement ? (
<div className="submitmsg">
{message && (
<span> Messaged received. I'll respond to your query ASAP! </span>
)}
</div>
) : (
<div> </div>
)}{" "}
</div>
{errors.name && (
<div>
<span>{errors.name.message}</span>
</div>
)}
{errors.message && (
<div>
<span>{errors.message.message}</span>
</div>
)}
{errors.email && (
<div>
<span>{errors.email.message}</span>
</div>
)}
{errors.mobile && (
<div>
<span>{errors.mobile.message}</span>
</div>
)}
</div>
);
}
You have to first initialize handleSubmit as below.
const {handleSubmit} = useForm();
Then in the form, onSubmit should be as below.
<form onSubmit={handleSubmit(onSubmit)}>
"onSubmit" is the method that is used to write the code in submitting form.
Regards.
In your code, it should be as below.
const onSubmit = (e) => {
e.preventDefault();
emailjs.sendForm('', '', e.target, '')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
e.target.reset();
setMessage(true);
setShowElement(true);
setTimeout(function () {
setShowElement(false);
}, 4000);
};
I am getting state values while clicking submit button but I am unable to do the validation for my login form and how to display the error messages below the input field when I enter my input wrong or empty. please give me a solution to this.Thanks in advance.
const Login = () => {
const [state, setState] = useState({
email: "",
password: ""
});
const handleChange = (e) => {
const {id, value} = e.target
setState(prevState => ({
...prevState,
[id]: value
}))
}
const handleSubmitClick = (e) => {
e.preventDefault();
console.log("Authenticated",state);
}
return(
<>
<div className="container">
<div className="title">
<form onSubmit={handleSubmitClick}>
<div className="form-group">
<input
type="email"
className="email"
placeholder="Email"
value={state.email}
onChange={handleChange}/>
</div>
<div className="form-group">
<input
type="password"
className="password"
placeholder="Password"
value={state.password}
onChange={handleChange}/>
</div>
<button type="submit" className="button">Enter</button>
</form>
</div>
</div>
</>
)
}
export default Login;
If you want to perform client-side validation, you can create hook like this:
const useEmailValidation = (email) => {
const isEmailValid = /#/.test(email); // use any validator you want
return isEmailValid;
};
And then you can use this hook in your form component:
...
const isEmailValid = useEmailValidation(state.email);
const isPasswordValid = usePasswordValidation(state.password);
const isFormValid = isEmailValid && isPasswordValid;
return (
...
<input
className={classNames({ 'invalid': !isEmailValid })}
type="email"
value={state.email}
onChange={handleChange}
/>
{!isEmailValid && 'Some error message'}
<button type="submit" disabled={!isFormValid} className="button">Enter</button>
...
);
...
Your validator hook can return validation message instead of boolean, like:
const useEmailValidation = (email) => {
if (!email || email.length === 0) {
return 'Email cannot be empty';
}
const isEmailValid = /#/.test(email); // use any validator you want
if (!isEmailValid) {
return 'Invalid email provided';
}
return null;
};
Also it is a good practice to show validation message only after field was focused before and after user tried to submit the form.
Formik is a great plugin that will help you perform form validation. The examples are also quite clear.
Or you could do something like this:
const Login = () => {
const [error, setError] = useState(null);
const [state, setState] = useState({
email: '',
password: '',
});
const validateEmail = (email) => {
const re =
/^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
};
const handleChange = (e) => {
const { id, value } = e.target;
setState((prevState) => ({
...prevState,
[id]: value,
}));
};
const handleSubmitClick = (e) => {
e.preventDefault();
if (!validateEmail(state.email)) {
setError('Invalid Email');
}
if (state.password.length < 8) {
setError('Password must be at least 8 chars long');
}
if (!error) {
// No errors.
}
};
return (
<>
<div className='container'>
<div className='title'>
{error && <div style={{ color: 'red' }}>{error}</div>}
<form onSubmit={handleSubmitClick}>
<div className='form-group'>
<input
type='email'
className='email'
placeholder='Email'
value={state.email}
onChange={handleChange}
/>
</div>
<div className='form-group'>
<input
type='password'
className='password'
placeholder='Password'
value={state.password}
onChange={handleChange}
/>
</div>
<button type='submit' className='button'>
Enter
</button>
</form>
</div>
</div>
</>
);
};
export default Login;
For an empty validation you can check it preventing the submit if the field is empty, like
const handleSubmitClick = (e) => {
e.preventDefault();
if(email.trim() === '' || password.trim() === ''){
//Add a h1 or section with the error message
}else{
console.log("Authenticated",state);
}
}
As long as the email field type is equal to email, which is your case, the browser should give an alert if the string is not an email. ("user#example.com")
I m new to react and js.
import React from "react";
import { useState, useEffect } from "react";
const Forminput = () => {
const [errors, setErrors] = useState({}); //state values
const [values, setValues] = useState({
username: "",
email: "",
}); //state values
const change = (e) => {
const { name, value } = e.target;
setValues({
...values,
[name]: value,
});
};
const submitChange = (e) => {
e.preventDefault();
console.log(values);
setErrors(validation(values));
console.log(errors);
};
const validation= (values) => {
if (!values.username.trim()) {
errors.username = "Username required";
}
if (!values.email) {
errors.email = "Email required";
} else if (!/\S+#\S+\.\S+/.test(values.email)) {
errors.email = "Email address is invalid";
}
return errors;
};
useEffect(() => {}, [errors]);
return (
<div>
<h2>Create Your Form </h2>
<form action="" className="form-inputs" onSubmit={submitChange}>
<div className="username">
<label htmlFor="username" className="username">
Username
</label>
<input
id="username"
type="text"
className="username"
name="username"
onChange={change}
value={values.username}
/>
{errors.username && <p>{errors.username}</p>}
</div>
<div className="email">
<label htmlFor="email" className="email">
email
</label>
<input
id="email"
type="text"
name="email"
className="email"
onChange={change}
value={values.email}
/>
{errors.email && <p>{errors.email}</p>}
</div>
<input type="submit" className="signup" />
</form>
</div>
);
};
setErrors state is not updating.
Two fields username and email. when entered username and not email first for time the errors state is updating.
when entered again right email then press submit it is not updating the error state but updating the values state. i tried using useeffect() but not working.
i new here could you please me.
I want to update the errors state too when i update values state. is this right way or help me
This happens because you're mutating the errors object in validation and setting the same errors object when you call setErrors in submitChange. Since errors is the same object reference, this doesn't trigger a re-render. You'll need to return a new object from validation:
const validation= (values) => {
const result = {};
if (!values.username.trim()) {
result.username = "Username required";
}
if (!values.email) {
result.email = "Email required";
} else if (!/\S+#\S+\.\S+/.test(values.email)) {
result.email = "Email address is invalid";
}
return result;
};
I am working on React in that project I am trying to write validations for Email and password by
using react hooks But I don't know how to start it write it so please help to achieve this.
What I want exactly is I hard coded Email and Password in my code. Now Just I want to write validations for Email and Password. What I want exactly is If I enter Incorrect Email and Correct password then in Validations it have to show only please enter valid email address.
If I enter correct Email then it has to show please enter correct password. If both are wrong means then it has to show validations please enter correct Email and Password.
This is my code
import React, { useState } from 'react';
import './Login.css';
const Login = () => {
const [loginData, setLoginData] = useState(null)
const loginCredentials = () => {
if (loginData.email === 'john#gmail.com' && loginData.password === 'christina') {
} else {
}
}
const handleChange = ({ target }) => {
const { name, value } = target
const newData = Object.assign({}, loginData, { [name]: value })
setLoginData(newData)
}
const handleSubmit = (e) => {
e.preventDefault()
loginCredentials()
}
return (
<div className='container'>
<div className='row justify-content-center'>
<div className='col-4'>
<div className='mainform mt-3'>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email</label>
<input type="email" name='email' className="form-control" id="email" onChange={handleChange}></input>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" name='password' className="form-control" id="password" onChange={handleChange}></input>
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</div>
)
}
export default Login
Try saving the errors in an array and check the length of array at the end.
const [errors,setErrors]=useState([]);
.
.
.
if(username !='john#gmail.com')
{
setErrors([...errors,{error:'Invalid username'}])
}
if(password!='something')
{
setErrors([...errors,{error:'Invalid password'}])
}
Now inside of the component
{errors?errors.map(elem=>elem.error):null}
You can create a state for the error message and change its value based on what combination of email and password is incorrect. If
const [errorMessage, setErrorMessage] = useState('')
const loginCredentials = () => {
if (loginData.email !== 'john#gmail.com' && loginData.password !== 'christina') {
setErrorMessage('email and pw are both incorrect')
} else if (loginData.email !== 'john#gmail.com' {
setErrorMessage('email is incorrect')
} else if {.....etc
}
then put {errorMessage} in your jsx where you want it to show up
You can use nested if else
const [error, setError] = useState("");
const loginCredentials = () => {
if (loginData.email === "john#gmail.com") {
if (loginData.password === "christina") {
setError("");
return true;
}
else
{
setError("Incorrect Password");
return false;
}
} else {
setError("Incorrect Email and password");
return false;
}
};
To show the error you can put a div somewhere in the form which will only show when there is error.
{error && <div>{error}</div>}
First of all, your input values are not controlled elements. learn about 'controlled component'.
There are lots of ways you can achieve this.
I think you can add a custom hook to handle onChange and reset handler.
custom hook:
import { useState } from 'react';
const useInputState = (initialValues) => {
const [state, setstate] = useState(initialValues);
const onChangeHandler = (e) => setstate({
...state,
[e.target.name]: e.target.value,
});
const reset = (field) => {
if (field) {
setstate({
...state,
[field]: initialValues[field],
});
} else {
setstate({
...initialValues,
});
}
};
return [state, onChangeHandler, reset];
};
export default useInputState;
Then consume that hook in your component.
import React, { useState } from 'react';
import UseInputState from '../hooks/useInputState';
const App = () => {
const [value, onChangeHandler, reset] = UseInputState('');
console.log({ value });
const [emailAlert, setEmailAlert] = useState(null);
const [passwordAlert, setPasswordAlert] = useState(null);
const loginCredentials = () => {
setEmailAlert(null);
setPasswordAlert(null);
const { email, password } = value;
if (email !== 'john#gmail.com') {
setEmailAlert('Please Enter valid Email Address');
}
if (password !== 'christina') {
setPasswordAlert(' please enter correct password');
}
reset('');
if (password === 'christina' && email === 'john#gmail.com') {
setEmailAlert(null);
setPasswordAlert(null);
}
};
const handleSubmit = (e) => {
e.preventDefault();
loginCredentials();
};
return (
<div className='container'>
<div className='row justify-content-center'>
<div className='col-4'>
<div className='mainform mt-3'>
<form onSubmit={handleSubmit}>
<div className='form-group'>
<label htmlFor='email'>Email</label>
<input
type='email'
name='email'
className='form-control'
id='email'
value={value.email || ''}
onChange={onChangeHandler}
></input>
</div>
<div className='form-group'>
<label htmlFor='password'>Password</label>
<input
type='password'
name='password'
className='form-control'
id='password'
value={value.password || ''}
onChange={onChangeHandler}
></input>
</div>
<button type='submit' className='btn btn-primary'>
Submit
</button>
</form>
{emailAlert && <div>{emailAlert}</div>}
{passwordAlert && <div>{passwordAlert}</div>}
</div>
</div>
</div>
</div>
);
};
export default App;