React 16x - قسمت 19 - کار با فرمها - بخش 2 - اعتبارسنجی ورودیهای کاربران
نویسنده: وحید نصیری
تاریخ: ۱۳۹۸/۰۹/۱۵ ۱۴:۲۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
class LoginForm extends Component {
state = {
account: { username: "", password: "" },
errors: {
username: "Username is required"
}
}; validate = () => {
return { username: "Username is required." };
};
handleSubmit = e => {
e.preventDefault();
const errors = this.validate();
console.log("Validation errors", errors);
this.setState({ errors });
if (errors) {
return;
}
// call the server
console.log("Submitted!");
}; validate = () => {
const { account } = this.state;
const errors = {};
if (account.username.trim() === "") {
errors.username = "Username is required.";
}
if (account.password.trim() === "") {
errors.password = "Password is required.";
}
return Object.keys(errors).length === 0 ? null : errors;
};
import React from "react";
const Input = ({ name, label, value, error, onChange }) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<input
value={value}
onChange={onChange}
id={name}
name={name}
type="text"
className="form-control"
/>
{error && <div className="alert alert-danger">{error}</div>}
</div>
);
};
export default Input; render() {
const { account, errors } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<Input
name="username"
label="Username"
value={account.username}
onChange={this.handleChange}
error={errors.username}
/>
<Input
name="password"
label="Password"
value={account.password}
onChange={this.handleChange}
error={errors.password}
/>
<button className="btn btn-primary">Login</button>
</form>
);
}
loginForm.jsx:55 Uncaught TypeError: Cannot read property 'username' of null at LoginForm.render (loginForm.jsx:55)
this.setState({ errors: errors || {} }); handleChange = ({ currentTarget: input }) => {
const errors = { ...this.state.errors }; //cloning an object
const errorMessage = this.validateProperty(input);
if (errorMessage) {
errors[input.name] = errorMessage;
} else {
delete errors[input.name];
}
const account = { ...this.state.account }; //cloning an object
account[input.name] = input.value;
this.setState({ account, errors });
}; validateProperty = ({ name, value }) => {
if (name === "username") {
if (value.trim() === "") {
return "Username is required.";
}
// ...
}
if (name === "password") {
if (value.trim() === "") {
return "Password is required.";
}
// ...
}
}; const Joi = require('@hapi/joi');
const schema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
password: Joi.string().pattern(/^[a-zA-Z0-9]{3,30}$/),
email: Joi.string().email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
});
schema.validate({ username: 'abc', birth_year: 1994 }); > npm install @hapi/joi --save > npm i --save-dev @types/hapi__joi
import Joi from "@hapi/joi";
schema = {
username: Joi.string()
.required()
.label("Username"),
password: Joi.string()
.required()
.label("Password")
}; validate = () => {
const { account } = this.state;
const validationResult = Joi.object(this.schema).validate(account, {
abortEarly: false
});
console.log("validationResult", validationResult);
validate = () => {
const { account } = this.state;
const validationResult = Joi.object(this.schema).validate(account, {
abortEarly: false
});
console.log("validationResult", validationResult);
if (!validationResult.error) {
return null;
}
const errors = {};
for (let item of validationResult.error.details) {
errors[item.path[0]] = item.message;
}
return errors;
};
validateProperty = ({ name, value }) => {
const userInputObject = { [name]: value };
const propertySchema = Joi.object({ [name]: this.schema[name] });
const { error } = propertySchema.validate(userInputObject, {
abortEarly: true
});
return error ? error.details[0].message : null;
}; <button disabled={this.validate()} className="btn btn-primary">
Login
</button>
schema = {
username: Joi.string()
.alphanum()
.min(5)
.max(15)
.messages({
"string.empty": "نام کاربری وارد نشده است",
"string.min": "حداقل تعداد حروف 5 کاراکتر میباشد",
"string.max": "حداکثر تعداد حروف مجاز 15 کاراکتر میباشد",
"string.alpha": "از حروف و عدد استفاده نمایید"
}),
password: Joi.string()
.min(5)
.max(12)
.alphanum()
.required()
.messages({
"string.empty": "رمز عبور وارد نشده است",
"string.min": "حداقل تعداد حروف 5 کاراکتر میباشد",
"string.max": "حداکثر تعداد حروف مجاز 15 کاراکتر میباشد",
"string.alpha": "از حروف و عدد استفاده نمایید"
}),
confirmation:
Joi.any().valid(Joi.ref('password'))
.messages({
"any.only": "رمز عبور مطابقت ندارد"
})
}; schema = schema = Joi.object().keys({
username: Joi.string().regex(/[a-zA-Z0-9]{3,30}/).min(3).max(30).required(),
password: Joi.string().regex(/[a-zA-Z0-9]{3,30}/),
confirmation: Joi.ref('password')
})
.with('password', 'confirmation'); password: Joi.string().min(3).max(15).required(),
password_confirmation: Joi.any().valid(Joi.ref('password')).required().options({ language: { any: { allowOnly: 'must match password' } } }) confirmPassword: Joi.string().required().valid(Joi.ref('password')).options({
language: {
any: {
allowOnly: '!!Passwords do not match',
}
}
}) firstName: Joi.string().min(5).max(10).required().error(errors => {
errors.forEach(err => {
switch (err.type) {
case "any.empty":
err.message = "Value should not be empty!";
break;
case "string.min":
err.message = `Value should have at least ${err.context.limit} characters!`;
break;
case "string.max":
err.message = `Value should have at most ${err.context.limit} characters!`;
break;
default:
break;
}
});
return errors;
}), validateProperty = ({ name, value }) => {
const userInputObject = { [name]: value };
const propertySchema = Joi.object({ [name]: this.schema[name] });
const { error } = propertySchema.validate(userInputObject, {
abortEarly: true
});
if (Object.keys(userInputObject)[0] === 'confirmation') {
if (value !== this.state.data.password)
return "گذرواژهها با هم تطابق ندارند"
}
return error ? error.details[0].message : null;
} confirmation:
Joi.string()
.min(5)
.max(12) renderInput(name, label, type = "text", correspond) {
const { data, errors } = this.state;
return (
<Input
name={name}
type={type}
label={label}
value={data[name]}
onChange={this.handleChange}
error={errors[name]}
correspond={correspond}
/>
);
} <form onSubmit={this.handleSubmit}>
{this.renderInput("username", "Username")}
{this.renderInput("password", "Password", "password")}
{this.renderInput(
"confirmPassword",
"Confirm Password",
"password",
"password"
)}
{this.renderInput("name", "Name")}
{this.renderButton("Register")}
</form> state = {
data: { username: "", password: "", name: "", confirmPassword: "" },
errors: {},
};
schema = {
username: Joi.string()
.required()
.email({ minDomainSegments: 2, tlds: { allow: ["com", "net", "info"] } })
.label("Username"),
password: Joi.string().required().min(5).label("Password"),
name: Joi.string().required().label("Name"),
confirmPassword: Joi.any().valid(Joi.ref("password")).required().messages({
"any.only": "با رمز عبور مطابقت ندارد",
}),
}; validateProperty = ({ name, value, attributes }) => {
const userInputObject = { [name]: value };
const schemaMap = { [name]: this.schema[name] };
if (attributes.correspond) {
const correspondFieldName = attributes.correspond.value;
userInputObject[correspondFieldName] = this.state.data[
correspondFieldName
];
schemaMap[correspondFieldName] = this.schema[correspondFieldName];
}
const propertySchema = Joi.object(schemaMap);
const { error } = propertySchema.validate(userInputObject, {
abortEarly: true,
});
return error ? error.details[0].message : null;
};