react-form-with-constraints-bs4beta v0.1.0
react-form-with-constraints
Simple form validation for React in ~400 lines of code
- Installation:
npm install react-form-with-constraints - CDN: https://unpkg.com/react-form-with-constraints/dist/
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:
- Making Forms Fabulous with HTML5
- Constraint Validation: Native Client Side Validation for Web Forms
- MDN - Form data validation
- MDN - Form input types
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>Examples
- CodePen basic example: https://codepen.io/tkrotoff/pen/BRGdqL
- CodeSandbox Bootstrap 4 example: https://codesandbox.io/s/qk0zro1qm4
- CodeSandbox WizardForm example: https://codesandbox.io/s/my0ojyzq6p
- CodeSandbox SignUp example: https://codesandbox.io/s/62qwozvm0k
- CodeSandbox ClubMembers example: https://codesandbox.io/s/q8364yn60j

Other examples inside the examples directory.
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.
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"FieldFeedbacksfor: string=> refer to anameattribute (e.g<input name="username">), should be unique to the current formshow?: 'first' | 'all'=> display the first error/warning encountered (default) or all of them
Note: you can place
FieldFeedbacksanywhere and have as many as you want for the samefieldFieldFeedbackwhen:ValidityStatestring | '*' | function=> HTML5 constraint violation name or a callbackerror?: boolean=> treat the feedback as an error (default)warning?: boolean=> treat the feedback as a warninginfo?: boolean=> treat the feedback as an info
FormWithConstraintsvalidateFields(...inputsOrNames: Array<Input | string>): void=> should be called when afieldchanges or theformis submitted, will re-render the properFieldFeedbacksisValid(): boolean
Browser support
You can use HTML5 attributes like type="email", required, pattern..., in this case a recent browser is needed,...
<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>...or ignore them and rely on when functions:
<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>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
readonlyordisabledinput won't trigger any HTML5 form constraint likerequired. - With
<input type="number">it's better to useonInputinstead ofonChange, see https://github.com/facebook/react/issues/11142
8 years ago