I am currently trying to add validation to a form that is built using material-ui components. I have it working but the problem is that the way I am currently doing it the validation function is currently being called on every state change in the input (i.e. every letter that is typed). However, I only want my validation to occur once the typing has stopped.
Given my current code:
class Form extends React.Component {
state = {open: false, email: '', password: '', email_error_text: null, password_error_text: null, disabled: true};
handleTouchTap() {
this.setState({
open: true,
});
}
isDisabled() {
let emailIsValid = false;
let passwordIsValid = false;
if (this.state.email === "") {
this.setState({
email_error_text: null
});
} else {
if (validateEmail(this.state.email)) {
emailIsValid = true
this.setState({
email_error_text: null
});
} else {
this.setState({
email_error_text: "Sorry, this is not a valid email"
});
}
}
if (this.state.password === "" || !this.state.password) {
this.setState({
password_error_text: null
});
} else {
if (this.state.password.length >= 6) {
passwordIsValid = true;
this.setState({
password_error_text: null
});
} else {
this.setState({
password_error_text: "Your password must be at least 6 characters"
});
}
}
if (emailIsValid && passwordIsValid) {
this.setState({
disabled: false
});
}
}
changeValue(e, type) {
const value = e.target.value;
const nextState = {};
nextState[type] = value;
this.setState(nextState, () => {
this.isDisabled()
});
}
login() {
createUser(this.state.email, this.state.password);
this.setState({
open: false
});
}
render() {
let {open, email, password, email_error_text, password_error_text, disabled} = this.state;
const standardActions = (
<FlatButton
containerElement={<Link to="/portal" />}
disabled={this.state.disabled}
label="Submit"
onClick={this.login.bind(this)}
/>
);
return (
<div style={styles.container}>
<Dialog
open={this.state.open}
title="Enter Your Details to Login"
actions={standardActions}
>
<span className="hint--right hint--bounce" data-hint="Enter in your email address">
<TextField
hintText="Email"
floatingLabelText="Email"
type="email"
errorText={this.state.email_error_text}
onChange={e => this.changeValue(e, 'email')}
/>
</span>
<br />
<span className="hint--right hint--bounce" data-hint="Enter your password">
<TextField
hintText="Password"
floatingLabelText="Password"
type="password"
errorText={this.state.password_error_text}
onChange={e => this.changeValue(e, 'password')}
/>
</span>
</Dialog>
<h1>VPT</h1>
<h2>Project DALI</h2>
<RaisedButton
label="Login"
primary={true}
onTouchTap={this.handleTouchTap.bind(this)}
/>
</div>
);
}
}
export default Form;
Is there a way that I can achieve my desired functionality, without making a major change to the code, or does it need to be completely refactored?
Form validation in React allows an error message to be displayed if the user has not correctly filled out the form with the expected type of input. There are several ways to validate forms in React; however, this shot will focus on creating a validator function with validation rules.
To invalidate a TextField in React Material UI, we set the error and helperText props of the TextField to display the error message we want. We set the error prop to make the TextField 's border red when we enter invalid input. And we set the helperText prop to display the error text at the bottom.
Material-UI supports the most recent versions of React, starting with ^16.8. 0 (the one with the hooks). Have a look at the older versions for backward compatibility.
Does the check have to happen after a certain delay? A solution that I think would suffice in most situations would be to split your code up a bit. Don't trigger your isDisabled()
function in changedValue()
. Instead have it run on the onBlur
event instead.
Try this:
<TextField
hintText="Password"
floatingLabelText="Password"
type="password"
errorText={this.state.password_error_text}
onChange={e => this.changeValue(e, 'password')}
onBlur={this.isDisabled}
/>
and then your function becomes:
changeValue(e, type) {
const value = e.target.value;
const nextState = {};
nextState[type] = value;
this.setState(nextState);
}
Current Material-UI version doesn't use the errorText
prop but there is still a way that you can use to display error and apply validation to the TextField in Material-UI.
We use the error
(Boolean) property to denote if there is an error or not. Further to display the error text use helperText
property of the TextField in the Material-UI, just provide it the error text you want to display.
Do it like:
<TextField
value={this.state.text}
onChange={event => this.setState({ text: event.target.value })}
error={text === ""}
helperText={text === "" ? 'Empty!' : ' '}
/>
Simplest is to call form.reportValidity()
. form
can be obtained by calling event.currentTarget.form
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With