https://github.com/pacdiv/hoc-form
Concise form validation for React! π
https://github.com/pacdiv/hoc-form
babeljs form form-builder form-validation higher-order-component javascript react reactjs
Last synced: 8 months ago
JSON representation
Concise form validation for React! π
- Host: GitHub
- URL: https://github.com/pacdiv/hoc-form
- Owner: pacdiv
- License: mit
- Created: 2018-04-13T07:03:52.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-07-30T06:48:31.000Z (almost 8 years ago)
- Last Synced: 2025-02-02T00:24:55.349Z (over 1 year ago)
- Topics: babeljs, form, form-builder, form-validation, higher-order-component, javascript, react, reactjs
- Language: JavaScript
- Homepage:
- Size: 215 KB
- Stars: 16
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# hoc-form β’    
Tired of writing custom form validation on every project you might work on? Letβs try `hocForm`, form validation on React has rarely been so simple! π€
# Requirements
hocForm needs at least react@16.3.1 and react-dom@16.3.1 to work.
# Installation
Using `npm`:
```
npm install --save hoc-form
```
`yarn add hoc-form` works fine too!
# Usage
```javascript
import React from 'react';
import hocForm, { Field } from 'hoc-form';
// First, we need a input component to render our text field
function Input({
input = {},
label = '',
meta = {},
placeholder = '',
type = 'text',
}) {
return (
{label}
input.onBlur && input.onBlur(e.target.value)}
onChange={e => input.onChange(e.target.value)}
/>
{meta.error && {meta.error}}
);
}
// Then, we need to create our form component and its helpers
const unavailableUsernames = [
'elonmusk',
'ironman',
'lukeskywalker',
];
function validateLogin(value = '') {
if (value.trim() === '') {
return Promise.reject('Please enter an username');
}
return unavailableUsernames.includes(value)
? Promise.reject('This username is unavailable')
: Promise.resolve()
}
function validatePassword(value = '') {
if (value.trim().length < 6) {
return Promise.reject('Password must contain 6 characters or more');
}
return Promise.resolve();
}
function Form({ onSubmit }) {
return (
validateLogin(value),
placeholder: 'elonmusk',
type: 'string',
}}
/>
Sign up
);
}
// Finally, an export of our wrapped form component
// with a validation function
export default hocForm({
validate(values, props) {
let errors = {};
const errorCatcher = (key, callback, ...args) => (
callback(values[key], args)
.catch(error => ({ [key]: error }))
);
return Promise.all([
errorCatcher('login', validateLogin),
errorCatcher('pwd', validatePassword),
]).then((errors) => {
const results = errors.reduce((acc, item) => ({ ...acc, ...item }), {});
return Object.keys(results).length ? Promise.reject(results) : Promise.resolve();
});
}
})(Form);
```
Please check out the [complete demo](https://github.com/pacdiv/hoc-form/tree/master/demo)! π
# API
## `hocForm({ options })(MyFormComponent) => React.Component`
Renders your `MyFormComponent` contexted with `hocForm`.
Two arguments are required:
- An `options` object to define the `validate` function and optional `initialValues`
- A form `React.Component` to render.
### `options.validate(values, props) => Promise`
Validates the form on submit.
Arguments:
1. `values` (`Object`): An object containing all fields keys and their value.
2. `props` (`Object`): An object containing all props provided to `MyFormComponent`.
Returns:
- A promise:
- On success, your must return `Promise.resolve()`
- In case of failure, your must return `Promise.reject({})`. The object parameter must contain every field key with its error (type of string or else, depends on how your components used with `Field` are designed).
Example, with errors as strings:
```javascript
function validate(values, props) {
let errors = {};
if (values.username) {
if (!props.isUsernameAvailable(values.username)) {
errors = { ...errors, username: 'This username is unavailable' };
}
} else {
errors = { ...errors, username: 'Please enter an username' };
}
if (!values.password) {
errors = { ...errors, password: 'Please enter a password' };
}
return Object.keys(errors).length
? Promise.reject(errors)
: Promise.resolve();
}
```
### `options.initialValues: Object`
Object containing all initial values following fields keys.
Example:
```javascript
initialValues: {
country: 'United Kingdom',
phone: '+44',
}
```
### `MyFormComponent: React.Component`
A `React.Component` rendering a form including some `hocForm.Field` items.
Example:
```javascript
function Form({ onSubmit }) {
return (
/>
);
}
```
Please check out a [complete example here](https://github.com/pacdiv/hoc-form/tree/master/demo).
## `Field({ options }) => React.Component`
Renders a form field, contexted with `hocForm`.
### `options.name: String`
The name used in your `options.validate` function.
Example:
```javascript
```
### `options.component: React.Component`
The `React.Component` rendered by `Field`.
Example:
```javascript
```
### `options.props: Object`
The properties provided to the `component` parameter.
Example:
```javascript
Promise.resolve(),
placeholder: 'elonmusk',
type: 'string',
}}
/>
```
Please check out a [complete example here](https://github.com/pacdiv/hoc-form/tree/master/demo).
## Which extra-props my components receive from `Field`?
Components used in `Field` must handle the two following properties: `input` and `meta`. Please check out the description below.
### `input.onChange(value: *)`
Allows to dispatch the new value of the field to the `hocForm` state. With this, all you have to do is to run `input.onChange(theNewValue)` to allow `hocForm` to use this new value at validation.
Example:
```javascript
function TextInput({
input = {},
}) {
return (
input.onChange(e.target.value)}
/>
);
}
```
### `input.onBlur(value: *, values: Object) => Promise`
Allows to run a validation on blur, the `onBlur` callback setted as property of the `Field`.
Example:
```javascript
function TextInput({
input = {},
}) {
return (
input.onBlur && input.onBlur(e.target.value)}
/>
);
}
```
**Note:**
When `Field` runs the optional `onBlur` callback received from its `props` property, it runs this callback with two arguments:
- `value: *`, which is the current value of the `Field`;
- `values: Object`, object containing all fields keys with their respective value. As example, this argument can be useful if you need to compare a Β« confirmation password Β» field with a previous Β« create password Β» field.
This callback must a return a Promise:
- `Promise.resolve()` if this blur validation succeeds;
- `Promise.reject(error)` in case of failure.
Example:
```javascript
(
currentValue.trim() !== values.firstPassword)
? Promise.reject('Please enter the same password as below')
: Promise.resolve()
),
}}
/>
```
### `options.meta: Object`
Object containing about a potential error on the field.
Example:
```javascript
function TextInput({
meta = {},
input = {},
}) {
return (
input.onBlur && input.onBlur(e.target.value)}
/>
{meta.error && {meta.error}}
);
}
```
Please check out a [complete example here](https://github.com/pacdiv/hoc-form/tree/master/demo).
# License
hocForm is [MIT licensed](https://github.com/pacdiv/hoc-form/blob/master/LICENSE).