JSPM

  • Created
  • Published
  • Downloads 4
  • Score
    100M100P100Q53696F
  • License MIT

a clean, simple form framework for react

Package Exports

  • react-formstate

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-formstate) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

react-formstate

Coverage Status Build Status

a clean, simple form framework for react

design remarks

  • no mixin or decoration, just an api
  • form state lives with your form component until the form is submitted with valid data
  • framework simply provides props, you lay out your inputs
  • works with react controlled components

setup

$ npm install react-formstate --save

example

import React from 'react';
import { FormState, FormObject } from 'react-formstate';
import Input from './Input.jsx';

export default class LoginForm extends React.Component {

  constructor(props) {
    super(props);
    this.formState = new FormState(this);

    // if you were editing a model, you could "inject" props.model
    this.state = this.formState.createUnitOfWork().injectModel();

    // since we're not injecting a model, the above is equivalent to
    this.state = {};

    this.handleSubmit = this.handleSubmit.bind(this);
  }

  render() {
    let submitMessage = '';
    if (this.formState.isInvalid()) {
      submitMessage = 'Please fix validation errors';
    }
    return (
      <form>
        <FormObject formState={this.formState}>
          <Input formField='username' label='Username' required />
          <Input formField='password' label='Password' required type='password' />
        </FormObject>
        <input type='submit' value='Submit' onClick={this.handleSubmit} />
        <span>{submitMessage}</span>
      </form>
    );
  }

  handleSubmit(e) {
    e.preventDefault();
    let model = this.formState.createUnitOfWork().createModel();
    if (model) {
      alert(JSON.stringify(model)); // proceed with valid data
    }
    // else: createModel called setState to set the appropriate validation messages
  }
}

your input component might look like

import React from 'react';

export default class Input extends React.Component {

  shouldComponentUpdate(nextProps, nextState) {
    return !nextProps.fieldState.equals(this.props.fieldState);
  }

  render() {
    console.log('render ' + this.props.label); // for demonstration only
    return (
      <div>
        <label>{this.props.label}</label>
        <input
          type={this.props.type || 'text'}
          value={this.props.fieldState.getValue()}
          onChange={this.props.updateFormState}
          />
        <span>{this.props.fieldState.getMessage()}</span>
      </div>
    );
  }
}

concise validation syntax

credit to joi for the inspiration

<Input
  formField='amount'
  label='Amount'
  required='Please provide an amount'
  fsValidate={v =>
    v.min(25)
    .message('Amount must be at least $25')
    .max(1000)
    .msg('Amount cannot be more than $1000')}
  />
<CheckboxGroup
  formField='roleIds'
  label='Roles'
  required='-'
  fsv={v => v.minLength(1).msg('Please select a role')}
  checkboxValues={this.roles}
  defaultValue={[]}
  intConvert
  />

features and examples

documentation

peer dependencies

  • react (!)
  • assumes es5 (for example: Object.keys and Array.isArray)