Reputation: 436
I have a react project. I need to validate 2 values from child components
Child component:
class PasswordField extends React.Component {
constructor(props) {
super(props);
this.state = {
password: '',
len: null,
upperCaseChar: null,
lowerCaseChar: null,
number: null,
};
this.passwordValidator = this.passwordValidator.bind(this);
}
passwordValidator(event) {
const string = event.target.value;
this.props.callback(event.target.value);
this.setState({
len: string.length >= 8 && string.length <= 30,
upperCaseChar: /[A-Z]/.test(string),
lowerCaseChar: /[a-z]/.test(string),
number: /\d/.test(string),
password: string
});
}
render() {
return (
<div>
<input className={styles.niceInput} type="password" name={this.props.formName} onChange={this.passwordValidator} placeholder={this.props.placeholder} required/><br/>
{this.state.len === false &&
<InformationElement error={true} message={"[8, 30]"}/>}
{this.state.upperCaseChar === false &&
<InformationElement error={true} message={"A"}/>}
{this.state.lowerCaseChar === false &&
<InformationElement error={true} message={"a"}/>}
{this.state.number === false &&
<InformationElement error={true} message={"1"}/>}
</div>
);
}
}
Parent component:
import React from 'react';
import UsernameField from "./UsernameField";
import PasswordField from "./PasswordField";
import InformationElement from "../InformationElement";
class RegistrationForm extends React.Component {
constructor(props) {
super(props);
this.state = {
api_base_url: "http://127.0.0.1",
api_base_port: "8000",
api_user_url: "/api/v1/user",
username: '',
password: '',
confirm_password: '',
passwords_are_similar: true,
username_is_ok: null
};
}
render() {
return <div className="form-group">
<form method="POST">
<label htmlFor="login" className="font-weight-bold">Registration</label>
<UsernameField
id="login"
className="container"
callbackUsername={(value) => this.setState({username: value})}
callbackStatus={(value) => this.setState({username_is_ok: value})}
api_base_url={`${this.state.api_base_url}:${this.state.api_base_port}${this.state.api_user_url}`}/>
<PasswordField
placeholder="Password"
formName="password"
callback={(value) => this.setState({password: value})}
/>
<PasswordField
placeholder="Confirm password"
formName="confirm_password"
callback={(value) => this.setState({confirm_password: value})}
/>
<br/>
{this.state.passwords_are_similar === false &&
<InformationElement error={true} message={"Passwords do not match"}/>}
<button type="button" className="btn btn-light" onClick={this.formSender}
disabled={this.state.username_is_ok !== true}>Registrate
</button>
</form>
</div>
}
}
export default RegistrationForm;
I want to get value from both PasswordField
s, but onChange
is already taken by passwordValidator
, so I can not pass (or I do not know how) another function. How to validate passwords in the parent component?
Also if there are any other problems in my code, feel free to point me, that is my first react project
Upvotes: 0
Views: 172
Reputation: 1805
Right so your parent component would be like this:
import React from 'react';
import PasswordField from "./PasswordField";
class RegistrationForm extends React.Component {
constructor(props) {
super(props);
this.state = {
api_base_url: "http://127.0.0.1",
api_base_port: "8000",
api_user_url: "/api/v1/user",
username: '',
password: '',
confirm_password: '',
passwords_are_similar: true,
username_is_ok: null
};
}
render() {
return <div className="form-group">
<form method="POST">
<label htmlFor="login" className="font-weight-bold">Registration</label>
<PasswordField
placeholder="Password"
formName="password"
callback={(value) => this.setState({password: value})}
/>
<PasswordField
placeholder="Confirm password"
formName="confirm_password"
callback={(value) => this.setState({confirm_password: value})}
/>
</form>
</div>
}
}
export default RegistrationForm;
And your PasswordField component would be like this:
class PasswordField extends React.Component {
constructor(props) {
super(props);
this.state = {
password: '',
len: null,
upperCaseChar: null,
lowerCaseChar: null,
number: null,
};
this.passwordValidator = this.passwordValidator.bind(this);
}
passwordValidator(event) {
const string = event.target.value;
this.props.callback(event.target.value);
this.setState({
len: string.length >= 8 && string.length <= 30,
upperCaseChar: /[A-Z]/.test(string),
lowerCaseChar: /[a-z]/.test(string),
number: /\d/.test(string),
password: string
});
}
onChange = (val) => {
const { callback } = this.props;
this.passwordValidator(val);
callback(val);
}
render() {
return (
<div>
<input className={styles.niceInput} type="password" name={this.props.formName} onChange={(e) => onChange(e.target.value)} placeholder={this.props.placeholder} required/><br/>
{this.state.len === false &&
<InformationElement error={true} message={"[8, 30]"}/>}
{this.state.upperCaseChar === false &&
<InformationElement error={true} message={"A"}/>}
{this.state.lowerCaseChar === false &&
<InformationElement error={true} message={"a"}/>}
{this.state.number === false &&
<InformationElement error={true} message={"1"}/>}
</div>
);
}
}
Might have some error missing but that would be the way.
Upvotes: 1