react-form-with-constraints
Simple form validation for React in ~400 lines of code
Introduction: what is HTML5 form validation?
<form>
<label for="email">Email:</label>
<input type="email" id="email" required>
<button>Submit</button>
</form>
The required
HTML5 attribute specifies that the user must fill in a value, type="email"
checks that the entered text looks like an email address.
Resources:
What react-form-with-constraints brings
- Minimal API and footprint
- Control HTML5 error messages:
<FieldFeedback when="valueMissing">My custom error message</FieldFeedback>
- Custom constraints:
<FieldFeedback when={value => ...}>
- Warnings and infos:
<FieldFeedback ... warning>
, <FieldFeedback ... info>
- No dependency beside React (no Redux, MobX...)
- No special component like
<TextField>
, just plain old <input>
or whatever you like - Re-render only what's necessary
- ...
<input type="password" name="password"
value={this.state.password} onChange={this.handleChange}
required pattern=".{5,}" />
<FieldFeedbacks for="password" show="all">
<FieldFeedback when="valueMissing" />
<FieldFeedback when="patternMismatch">
Should be at least 5 characters long
</FieldFeedback>
<FieldFeedback when={value => !/\d/.test(value)} warning>
Should contain numbers
</FieldFeedback>
<FieldFeedback when={value => !/[a-z]/.test(value)} warning>
Should contain small letters
</FieldFeedback>
<FieldFeedback when={value => !/[A-Z]/.test(value)} warning>
Should contain capital letters
</FieldFeedback>
<FieldFeedback when={value => !/\W/.test(value)} warning>
Should contain special characters
</FieldFeedback>
</FieldFeedbacks>
How it works
The API works the same way as React Router v4:
<Router>
<Route exact path="/" component={Home} />
<Route path="/news" component={NewsFeed} />
</Router>
It is also inspired by AngularJS ngMessages.
If you had to implement validation yourself, you would end up with a global object that tracks errors for each field.
react-form-with-constraints works similarly (although not using setState
).
It uses React context to share the FieldsStore
object across FieldFeedbacks
and FieldFeedback
.
Examples
Other examples inside the examples directory.
API
The API reads like this: "for field when constraint violation display feedback", example:
<FieldFeedbacks for="password">
<FieldFeedback when="valueMissing" />
<FieldFeedback when="patternMismatch">Should be at least 5 characters long</FieldFeedback>
</FieldFeedbacks>
for field "password"
when constraint violation "valueMissing" display "the HTML5 error message"
when constraint violation "patternMismatch" display "Should be at least 5 characters long"
Browser support
You can use HTML5 attributes like type="email"
, required
, pattern
..., in this case a recent browser is needed,...
<form onSubmit={this.handleSubmit} noValidate>
<label htmlFor="username">Username</label>
<input type="email" name="username" id="username"
value={this.state.username} onChange={this.handleChange}
required />
<FieldFeedbacks for="username">
<FieldFeedback when="*" />
</FieldFeedbacks>
<button>Submit</button>
</form>
...or ignore them and rely on when
functions:
<form onSubmit={this.handleSubmit} noValidate>
<label htmlFor="username">Username</label>
<input name="username" id="username"
value={this.state.username} onChange={this.handleChange} />
<FieldFeedbacks for="username">
<FieldFeedback when={value => value.length === 0}>Please fill out this field.</FieldFeedback>
<FieldFeedback when={value => !/\S+@\S+/.test(value)}>Invalid email address.</FieldFeedback>
</FieldFeedbacks>
<button>Submit</button>
</form>
In the last case you will have to manage translations yourself.
react-form-with-constraints, like React 16, depends on the collection types Map and Set.
If you support older browsers (<IE11) you will need a global polyfill such as core-js or babel-polyfill.
Notes
- A
readonly
or disabled
input won't trigger any HTML5 form constraint like required
.