Hyperapp form state management library
- Simple
- Small in size (3kb minified)
Heavily inspired by redux-form
npm i -S hyperapp-forms
Add the imported actions object contents to the main actions object.
importformsfrom'hyperapp-forms';..constactions={..
...forms,};..app(state,actions,view,document.body);Wrap your input components with the Field decorator.
Textbox.js
import{h}from'hyperapp';import{Field}from"hyperapp-forms";constTextbox=({ input, type, name, title, disabled })=>{constshowError=(input.touched||input.submitted)&&!!input.error;return(<label>{title}<inputtype={type}name={name}value={input.value}disabled={disabled}onchange={input.onchange}onfocus={input.onfocus}/>{showError&&<sup>{input.error}</sup>}</label>);};exportdefaultField(Textbox);The attributes the Field decorator adds to the component are:
| Attribute | Type | Description |
|---|---|---|
| form | string | The form's name |
| name | string | The field's name |
| validate | function(form, name, values) : Object | A validate function to run after change |
Changes a value for a certain field, also runs the validate function and updates the sync errors accordingly.
validate is a callback with the following structure validate(form, name, values) (see explanation above).
Sets the field as been touched.
Sets the form's status to be submitting
Sets the form's status to be not submitting, and apply server errors by matching field names.
| Selector | Description |
|---|---|
getFormValues(state, form) | Get an object with the form values |
isSubmitting(state, form) | Is the form submitting |
isValid(state, form) | Is the form valid (are there any errors) |
wasSubmitted(state, form) | Was the form submitted at least once (useful for showing errors) |
getFieldValue(state, form, field) | Get a certain field value |
getFieldError(state, form, field) | Get a certain field error |
isFieldTouched(state, form, field) | Was field touched (useful for showing errors) |
handleSubmit(state, actions, form, callback)
Use handleSubmit in the form's onsubmit (or any button's callback, see example below),
Supply a callback function which will return a promise, which at first will start the form's submission automatically.
And once resolved or rejected will stop the form's submission.
The callback function needs to be in the following structure:
callback(values, actions) : Promise
The resolve or reject argument should be
Checkout a working example: hyperapp-less-boilerplate
constsignIn=(values,actions)=>newPromise((resolve,reject)=>{setTimeout(()=>{if(values.username==='test'){actions.login.login();resolve();}else{reject({username: 'Not "test"!'});}},2000);});constvalidate=(form,name,values)=>{leterrors=null;constusernameInvalid=!/^t/.test(values.username);if(usernameInvalid){if(!errors)errors={};errors.username='not starting with t!';}constpasswordInvalid=!values.password;if(passwordInvalid){if(!errors)errors={};errors.password='password is required!';}returnerrors;// if everything is valid, returns null};exportdefault(state,actions)=>{constsubmitting=isSubmitting(state,'login');return(<formonsubmit={handleSubmit(state,actions,'login',signIn)}><h2>Login to your account:</h2><Textboxtype="text"form="login"name="username"title="Username"disabled={submitting}validate={validate}/><Textboxtype="password"form="login"name="password"title="Password"disabled={submitting}validate={validate}/><Checkboxform="login"name="rememberMe"title="Remember me"disabled={submitting}/><buttondisabled={submitting}>Sign In</button>{submitting&&<divdata-loader/>}</form>);});