Form assist
Create easy forms in react.
The problem
I have been using formik for a while now, and I really like it. My only problem with it, was the fact that sometimes the forms would become hard for me, to wrap my head around.
The solution
Make all the values and errors available outside the JSX
Installation
npm install --save form-assist
Usage
Basic example
import {useFormAssist, Form, Field} from "form-assist"
const initialValues = {
example: "",
}
const {formHelpers} = useFormAssist(initialValues)
function handleSubmit(event) {
console.log(formHelpers.values)
}
return (
<>
<Form formHelpers={formHelpers} onSubmit={handleSubmit}>
<Field name="example" />
</Form>
</>
)
useFormAssist
import {useFormAssist} from "form-assist"
const initialValues = {
example: "",
}
const {formHelpers, validation} = useFormAssist(
initialValues,
validationOptions
)
const {
values,
setValues,
errors,
setErrors,
touched,
handleChange,
handleBlur,
resetForm,
touchAllFields,
} = formHelpers
formHelpers
values
Values
The values will the current state of the initialValues, that you passed to the function
setValues
setValues
The setValues function is given to you for flexability, if you for some reason would like to set your form values, you can do that.
const {values, setValues} = formHelpers
setValues({...values, example: "you have been modified"})
errors
Errors
The errors object will be containing your initialValues object, but all strings. If at any point these strings have a value, the form will not submit
setErrors
setErrors
This function allows you to set an error on any given value, making it impossible to submit unless resolved.
const {errors, setErrors} = formHelpers
setErrors({...errors, example: "Unknown example!"})
touched
touched
The touched object will hold the state of whether the fields have been touched or not.
It can be very usefull together with the error state.
const {errors, touched} = formHelpers
const isThouchedAndError = errors.example && touched.example
handleChange
handleChange
Although not required in the Field component, the handleChange function can be passed in any input field inside your form.
const {values, handleChange} = formHelpers
return (
<>
<Form>
<input name="example" value={values.example} onChange={handleChange}>
</Form>
</>
)
handleBlur
handleBlur
This function will take care of setting a field to touched on blur.
const {values, handleBlur} = formHelpers
return (
<>
<Form>
<input name="example" value={values.example} onBlur={handleBlur}>
</Form>
</>
)
resetForm
resetForm
the resetForm function will compleatly reset both your form and also any errors that you may have.
const {values, resetForm} = formHelpers
function handleSubmit(event) {
e.preventDefault()
console.log("YAY i exist!", values)
resetForm()
console.log("I have been reset 😿", values)
}
touchAllFields
touchAllFields
If at any point you wish to make of the fields touched, this function can be
called, and it will do just that
Form
Form
The Form component is the way to bootstrap your form. Whenever you use a new
Form, it will need a few properties to function properly
formHelpers
formHelpers
The Form component needs to know which values, that it is working with..
Therefor, we pass it all of the formHelpers that you recieved whenever you
called useFormAssist()
const {formHelpers} = useFormAssist(initialValues)
return <Form formHelpers={formHelpers}></Form>
onSubmit
onSubmit
The onSubmit prop works just as a normal onSubmit, exept that before it is called, it will check whether or not an error is pressent.
If no error is found, it will call your onSubmit.
const {formHelpers} = useFormAssist(initialValues)
return (
<Form
formHelpers={formHelpers}
onSubmit={e => console.log(formHelpers.values)}></Form>
)
validation
validation
This is an object with error validation options.
Read more about this under the Validation section
Field
Field
The Field component is given to you, as an easy way to create fields of any kind. You can use it effectively, by passing it a type property, which will change which props needs to be given, for that specific type.
return (
<>
<Field type="radio" name="example" value="I will be this value" />
<Field type="radio" name="example" value="Another value" />
</>
)
Form assist also supports custom components through the element property.
const animals = [
{id: Math.random(), value: "Cat"},
{id: Math.random(), value: "Dog"},
]
return (
<Field
name="example"
type="select"
element={<SelectField />}
options={animals}
/>
)
This will create ALL of your select and insert your array's, values as key's or value respectively.
useField
useField
The useField hook allows you to grap a single field by it's name. This means that you can create custom components, and still have access to whether the field has an error or is touched.
Quick example with React Bootstrap
function MyTextField({name, label, ...props}) {
const {field, info} = useField(name)
const isError = info.error && info.touched ? info.error : ""
return (
<Form.Group controlId={name}>
{label && <Form.Label>{label}</Form.Label>}
<Form.Control {...field} {...props} isInvalid={!!isError} />
{isError && (
<Form.Control.Feedback type="invalid">{isError}</Form.Control.Feedback>
)}
</Form.Group>
)
}
This new MyInputField component could then be used as a replacement for the Field component
Validation
Form assist has validation build in, so you don't have to do any fancy things
yourself
All you have to do is provide a second parameter, to the useFormAssist hook.
const {formHelpers, validation} = useFormAssist(initialValues, {
example: {
required: {
is: true,
errorMessage: "This field is required",
},
minCharacters: {
is: 5,
},
maxCharacters: {
is: 10,
errorMessage: "You cannot pass more than 10 characters to this field",
},
},
})
You will then have to provide the validation object that is returned from the useFormAssist hook, into your Form component's props like so:
return <Form validation={validation}></Form>
And that's it! You now have validation on your fields.
Form assist does provide some default error messages, but if you want you can provide your own, just like in the example above.
All of this is typed, so it's really easy to figure out what you can pass to the
objects
Currently form assist supports these validation options:
- required
- minCharacters
- maxCharacters
- hasToInclude
Local Storage support
If you want your form to be persisted through local storage. The useFormAssistStorage hook is exactly what you need.
It works exactly like useFormAssist, except you have to pass it a local-storage key aswell.
import {useFormAssistStorage} from "form-assist"
const {formHelpers, validation} = useFormAssistStorage(
localStorageKey,
initialValues,
validationOptions
)
Issues
Looking to contribute? Any feedback is very appreciated.
🪲 Bugs
Please file an issue for bugs, missing documentation, or unexpected behavior.
🕯 Feature Requests
Please file an issue to suggest new features. Vote on feature requests by adding
a
✨
Contributors Thanks goes to these wonderful people (emoji key):
Tobias Zimmermann |
This project follows the all-contributors specification. Contributions of any kind welcome!