14
loading...
This website collects cookies to deliver better user experience
email
and password
with necessary properties - valid
, touched
, error
and touched
in the state using useState
hook .const [formData, setFormData] = useState({
email: { valid: true, value: "", error: "", touched: false },
password: { valid: true, value: "", error: "", touched: false }
});
<div className="row" style={{ marginTop: "100px" }}>
<div className="col-md-12">
<h4 className="text-center">Sign In</h4>
<form className="form-horizontal" onSubmit={onSubmit}>
<div className="form-group">
<label htmlFor="email" className="col-sm-2 control-label"> Email </label>
<div className="col-sm-10">
<input type="email" className="form-control" id="email" placeholder="Email" value={email.value} onChange={handleChange} name="email" autoComplete="off" />
<label className="label label-danger" style={{ display: email.touched && email.error ? "inline" : "none" }}> {email.error} </label>
</div>
</div>
<div className="form-group">
<label htmlFor="password" className="col-sm-2 control-label"> Password</label>
<div className="col-sm-10">
<input type="password" className="form-control" id="password" placeholder="Password" value={password.value} onChange={handleChange} name="password" />
<label className="label label-danger" style={{ display: password.touched && password.error ? "inline" : "none" }} > {password.error} </label>
</div>
</div>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button type="submit" className="btn btn-default">Sign in</button>
</div>
</div>
</form>
</div>
</div>
handleChange
method to handle the changes in the state with the user input.const handleChange = (e) => {
const target = e.target;
const { name, value } = target;
let prevFormData = { ...formData };
let error = validateFormField(name, value);
prevFormData[name] = {
...prevFormData[name],
value: value.trim(),
touched: true,
error
};
setFormData(prevFormData);
};
validateFormField
method. Here in this method, we check for multiple conditions and returns a respective error message.const validateFormField = (name, value) => {
let error = "";
if (name === "email") {
if (!value) {
error = "email is mandatory";
}
if (value) {
if (!/^\w+([\\.-]?\w+)*@\w+([\\.-]?\w+)*(\.\w{2,3})+$/.test(value)) {
error = "give a valid email";
}
}
}
if (name === "password") {
if (!value) {
error = "password is mandatory";
}
if (value) {
if (value.length < 3) {
error = "password should be atleast 3 characters";
}
if (value.length > 10) {
error = "password should not exceed 10 characters";
}
}
}
return error;
};
onSubmit
method. We need to check for the validity of the form, so as to do this, we need call validateFormField
looping through the state.const onSubmit = (event) => {
event.preventDefault();
let prevFormData = { ...formData };
let error;
let isValid = true;
for (let field in prevFormData) {
error = validateFormField(field, prevFormData[field]["value"]);
if (isValid && error) {
isValid = false;
}
prevFormData[field] = {
...prevFormData[field],
touched: true,
error
};
}
if (!isValid) {
setFormData(prevFormData);
} else {
alert(JSON.stringify(prevFormData));
}
};
<Formik>
{(props)=>{
return (
/* form comes here */
)
}}
</Formik>
<Formik
initialValues={{ email: "", password: "" }}
onSubmit={(values) => { /* submit handler */ }}
validate={(values)=>{/* validation handler */}} >
{(props) => {
return (
<form className="form-horizontal" onSubmit={props.handleSubmit}>
/* form elements come here */
</form>
);
}}
</Formik>
validate
prop.// vanilla React validation code
const handleChange = (e) => {
const target = e.target;
const {
name,
value
} = target;
let prevFormData = {
...formData
};
let error = validateFormField(name, value);
prevFormData[name] = {
...prevFormData[name],
value: value.trim(),
touched: true,
error
};
setFormData(prevFormData);
};
const validateFormField = (name, value) => {
let error = "";
if (name === "email") {
if (!value) {
error = "email is mandatory";
}
if (value) {
if (!/^\w+([\\.-]?\w+)*@\w+([\\.-]?\w+)*(\.\w{2,3})+$/.test(value)) {
error = "give a valid email";
}
}
}
if (name === "password") {
if (!value) {
error = "password is mandatory";
}
if (value) {
if (value.length < 3) {
error = "password should be atleast 3 characters";
}
if (value.length > 10) {
error = "password should not exceed 10 characters";
}
}
}
return error;
};
// Formik Validation
validate = {values => {
let errors = {};
if (!values.hasOwnProperty('email')) {
error = "email is mandatory";
} else {
if (!/^\w+([\\.-]?\w+)*@\w+([\\.-]?\w+)*(\.\w{2,3})+$/.test(values.email)) {
error = "give a valid email";
}
}
if (!values.hasOwnProperty('password')) {
error = "password is mandatory";
}else {
if (values.email < 3) {
error = "password should be atleast 3 characters";
}
if (values.email > 10) {
error = "password should not exceed 10 characters";
}
}
return errors;
}
}
useValidator
. We extracted the validation logic and put it in one hook 😎const useValidator = (validationsInfo) => {
return function (values) {
let errors = {};
for (let key in validationsInfo) {
let fieldValitions = validationsInfo[key];
let fieldValue = values[key];
for (let validationObejct of fieldValitions) {
let { type, value, message } = validationObejct;
let isValid = true;
switch (type) {
case "required":
if (value === true) {
if (!fieldValue && fieldValue !== 0) {
isValid = false;
}
}
break;
case "regex":
try {
const validationRegex = new RegExp(value, "g");
isValid = validationRegex.test(fieldValue) === true;
} catch (error) {}
break;
case "minlength":
if (fieldValue.length < value) {
isValid = false;
}
break;
case "maxlength":
if (fieldValue.length > value) {
isValid = false;
}
break;
case "exactlength":
if (fieldValue.length !== value) {
isValid = false;
break;
}
break;
case "minvalue":
fieldValue = +fieldValue;
if (fieldValue < value) {
isValid = false;
}
break;
case "maxvalue":
fieldValue = +fieldValue;
if (fieldValue > value) {
isValid = false;
}
break;
case "custom":
try {
if (typeof value === "function") {
isValid = value(fieldValue) === true;
}
} catch (error) {}
break;
default:
break;
}
if (!isValid) {
errors[key] = message;
break;
}
}
}
return errors;
};
};
export default useValidator;
Regex
, minlength
, maxlength
etc. Even we can execute a function using custom
.const validator = useValidator({
email: [
{
type: "required",
value: true,
message: "email is required"
},
{
type: "regex",
value:
"^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$",
message: "enter valid email"
}
],
password: [
{ type: "required", value: true, message: "password is required" },
{
type: "minlength",
value: 2,
message: "password should be minimum two length"
},
{
type: "custom",
value: function (val) {
if (typeof val !== "string") {
val = String(val);
}
if (val.length > 10) {
return false;
}
return true;
},
message: "password should not exceed 10 characters"
}
]
});
useValidator
hook will return a function, that we need to pass it to Formik with validate
prop.