README
useForm(๐, โ๏ธ) โ Reactive Form โ๏ธ
Reactive form management and input field validation hook
Create a form model, flag input fields as required or add a value validation function with custom error messages. useForm will validate the inputs as the user types, when there are no errors the form gets enabled for submission. On form submission, it executes a callback function the user provides.
Requirements:
- ๐ Form model with optional validation function.
- โ๏ธ Function to run after form validation and submission.
- โ๏ธ React functional component with a form.
Install
npm install reactjs-use-form
- ๐งช Tested using @testing-library/react-hooks.
- ๐๏ธ Built with Rollup and CRACO.
Usage
Steps:
- create a form model:
import { FormModelType } from 'reactjs-use-form';
export const formModel: FormModelType = {
currentPassphrase: {
value: '',
required: true,
},
newPassphrase: {
value: '',
required: true,
validator: (newPassphrase, values) => {
if (newPassphrase === values?.currentPassphrase) {
return 'New password must be different from current password';
} else if (newPassphrase.length <= 5) {
return 'Password must be at least 6 characters long';
} else if (newPassphrase !== values?.verifyPassphrase) {
return 'Passwords do not match';
} else return '';
},
},
verifyPassphrase: {
value: '',
required: true,
validator: (verifyPassphrase, values) => {
return verifyPassphrase !== values?.newPassphrase ? 'Passwords do not match' : '';
},
},
};
prepare a submit callback function, for example:
function handleSubmit() {...}
.use the form model with the callback function in useForm hook in a functional react component:
Plain JSX code example
import React from 'react';
import { useForm, ValuesType } from 'reactjs-use-form';
import { formModel } from './formModel';
const ChangePassphraseComponent = () => {
const {
values,
errors,
handleOnChange,
handleOnSubmit,
isDisabled,
isSubmitted
} = useForm(formModel, handleSubmit);
const { currentPassphrase, newPassphrase, verifyPassphrase }: ValuesType = values;
function handleSubmit() {
// formSubmitCallback();
}
return (
<form onSubmit={handleOnSubmit}>
<div>
<label>Current Passphrase</label>
<input
type="password"
name="currentPassphrase"
value={currentPassphrase}
onChange={handleOnChange}
/>
<span>{errors.currentPassphrase.message}</span>
</div>
<div>
<label>New Passphrase</label>
<input
type="password"
name="newPassphrase"
value={newPassphrase}
onChange={handleOnChange}
/>
<span>{errors.newPassphrase.message}</span>
</div>
<div>
<label>Verify Passphrase</label>
<input
type="password"
name="verifyPassphrase"
value={verifyPassphrase}
onChange={handleOnChange}
/>
<span>{errors.verifyPassphrase.message}</span>
</div>
<span>{isSubmitted ? 'Passphrase has been changed!' : null}</span>
<button type="submit" size="sm" disabled={isDisabled}>
<span>Submit</span>
</button>
</form>
);
};
Material-UI code example
import React from 'react';
import { Button, FormControl, FormGroup, FormHelperText, FormLabel, TextField } from '@material-ui/core';
import { useForm, ValuesType } from 'reactjs-use-form';
import { formModel } from './formModel';
const ChangePassphraseComponent = () => {
const {
values,
errors,
handleOnChange,
handleOnSubmit,
isDisabled,
isSubmitted
} = useForm(formModel, handleSubmit);
const { currentPassphrase, newPassphrase, verifyPassphrase }: ValuesType = values;
function handleSubmit() {
// formSubmitCallback();
}
return (
<form onSubmit={handleOnSubmit}>
<FormGroup>
<FormControl>
<TextField
required={true}
label='Current Passphrase'
type='password'
name='currentPassphrase'
error={errors.currentPassphrase.hasError}
value={currentPassphrase}
onChange={handleOnChange} />
<FormHelperText error={errors.currentPassphrase.hasError}>
{errors.currentPassphrase.message}
</FormHelperText>
</FormControl>
</FormGroup>
<FormGroup>
<FormControl>
<TextField
required={true}
label='New Passphrase'
type='password'
name='newPassphrase'
error={errors.newPassphrase.hasError}
value={newPassphrase}
onChange={handleOnChange} />
<FormHelperText error={errors.newPassphrase.hasError}>
{errors.newPassphrase.message}
</FormHelperText>
</FormControl>
</FormGroup>
<FormGroup>
<FormControl>
<TextField
required={true}
label='Verify Passphrase'
type='password'
name='verifyPassphrase'
error={errors.verifyPassphrase.hasError}
value={verifyPassphrase}
onChange={handleOnChange} />
<FormHelperText error={errors.verifyPassphrase.hasError}>
{errors.verifyPassphrase.message}
</FormHelperText>
</FormControl>
</FormGroup>
{isSubmitted ? <Alert variant='standard' severity='success' action='Passphrase has been changed!' /> : null}
<Button type='submit' disabled={isDisabled}>
Submit
</Button>
</form>
);
};
Options
useForm takes two params: formModel
and formSubmitCallback
, returns the rest.
const {
values,
errors,
handleOnChange,
handleOnSubmit,
isDisabled,
isSubmitted
} = useForm(formModel, formSubmitCallback);
Param | Type | Description |
---|---|---|
values | ValuesType |
returns form values state object |
errors | ErrorsType |
returns form errors state object |
handleOnChange | HandleOnChangeType |
binds to a HTMLInputElement: change event |
handleOnSubmit | HandleOnSubmitType |
binds to a HTMLFormElement: submit event |
isDisabled | boolean |
returns true / false when the form is valid / invalid |
isSubmitted | boolean |
returns true when the form was submitted without errors |
formModel | FormModelType |
initial form model with optional validation function |
formSubmitCallback | () => void |
function to run after form validation and submission |