redux-easy-forms
See it in action: REF DEMO
Full rewrite as of ver 0.3.0 -- smaller, cleaner, nicer API :)
Yet another forms solution
- Simplify dealing with client-side forms
- Define your form fields via a simple "schema" object
- Supply desired validation functions and error messages per field
- Use a friendly API to interact with your forms and data
- Obtain all JSX props for each input via a single API method call
Approach
REF exposes a small number of handy methods to cut down on common form-related chores. It maintains its "private" Redux state, eliminating the need for dispatching actions or connecting to the forms reducer directly. It is a fairly narrowly-focused abstraction, compatible with native HTML inputs and any React components which follow the same props (adaptable).
API Methods: clear | clearLiveErrors | get | getErrors | getLiveErrors | init | isDirty | isValid | props | restorePristine | saveAsPristine | set | setFocus
Install
npm install redux-easy-forms --save
or yarn add redux-easy-forms
- Define forms "schema" object and a validators object for ALL forms used throughout your app:
const schema = login: // specify unique key per each form password: type: 'password' // unique name per input within each form username: type: 'text' placeholder: 'Username' // specify type and any other valid props agreement: pin: type: 'tel' validators: 'isPin' // reference desired validator by key agree: // checkboxes/radios/select must be arrays type: 'checkbox' value: 'on' validators: 'isAgree' duration: type: 'select-one' value: 'day' selected: true // can have init value, checked, or selected type: 'select-one' value: 'week' type: 'select-one' value: 'month' ; const validators = isAgree: !!vallength error: 'You must agree to proceed' isPin: !!val error: 'PIN is required' vallength === 4 error: '4-digit PIN is required'
- Add
reformsReducer
to your Redux store and wrap your app with theReformsProvider
:
; const rootReducer =
- Then, for any component needing access to REForms, enhance it with the
withReforms
HOC:
; // <-- Component /* ... */ LoginPage; // <--
Of course, you can also compose in connect
to any of your other reducers:
mapStateToProps mapDispatchToProps; // <--
Or, if you enjoy using the decorator syntax:
@@withReformsComponent /* ... */
Usage
The enhanced component will now receive this.props.reforms
, which provides a handy API to your forms data:
const reforms = thisprops;
To render an input field in JSX:
<input ...reforms/>
The props
method returns all necessary props in one swoop (including name
, value
, onChange
, etc.)
Other API examples:
reforms; // --> username input gets focusedreforms; // --> 'Jane' appears in username fieldreforms; // --> 'Jane'reforms; // --> { username: 'Jane', password: '' }reforms; // --> true
API Reference
clear(form:String, [name:String])
Clear all fields within a given form, or a single field. Also reset the "touched" status, thus clearing any "live" validation errors.
reforms.clear('login')
clearLiveErrors(form:String, [name:String])
Reset the "touched" status of specified form field(s), thus clearing any "live" validation errors.
reforms.clearLiveErrors('login')
Object
or String|Array
get(form:String, [name:String]) ⇒ Get current form values (object of key-vals), or the value of a given form field (string, or an array of strings if multiple values). For multi-input arrays (checkboxes, radios, select-one) holding only one value element, it is delivered as a string.
reforms.get('login')
Object
or Array
getErrors(form:String, [name:String]) ⇒ Get validation errors for the entire form, or a given form field. Errors are arrays of strings, or an empty array (if no errors).
reforms.getErrors('login')
Object
or String
getLiveErrors(form:String, [name:String]) ⇒ Suitable for per-field errors while editing a form. Delivers only the first error, as long as the form/field is "touched" and not in focus.
reforms.getLiveErrors('login', 'username')
init(schema:Object)
Dynamically initialize additional form schema into REF. Existing form names will be "extended" in. Any validators referenced in the new schema must already be defined.
reforms.init({ 'note_2': { note: { type: 'text' } } })
Boolean
isDirty(form:String, [name:String]) ⇒ Check whether a form or a given field have changed from their "pristine" state. A form/field is considered "pristine" when first initialized, upon performing a set
, or saveAsPristine
.
reforms.isDirty('login')
Boolean
isValid(form:String, [name:String]) ⇒ Check whether a form or a given field have no validation errors.
reforms.isValid('login')
Object
props(form:String, name:String, [value:String]) ⇒ Get all JSX props for a given input field. For checkboxes and radios, the input's value is required (third argument). Returns the schema props along with REF-specific props, e.g. onChange
or onClick
handlers, ref
(used for setFocus
), plus onFocus
& onBlur
(to support getLiveErrors
logic).
reforms.props('login', 'username')
or reforms.props('login', 'agree', 'on')
restorePristine(form:String, [name:String])
Reset all form fields, or a given field, to their "pristine" state.
reforms.restorePristine('login')
saveAsPristine(form:String, [name:String])
Store current form state, or the state of a given field, as the new "pristine" state.
reforms.saveAsPristine('login')
set(form:String, payload:Object)
Set value(s) into one or more fields of a given form. The payload
must match the schema structure exactly, as it will be "extended" directly over the current field data. To be bullet-proofed in future versions, in the meantime, tread lightly!
reforms.set('login', { username: { value: 'me@example.com', disabled: true } })
setFocus(form:String, name:String)
Set focus to a given field.
reforms.setFocus('login', 'username')
Changelog
See Releases