1.7.2 • Published 6 years ago

formwood v1.7.2

Weekly downloads
29
License
MIT
Repository
github
Last release
6 years ago

Formwood

A small library for building forms and validation with React.

npm version Travis build status Coverage Status Dependency Status devDependency Status

Usage

Install the package with npm.

npm install --save formwood

Import the Field and Form modules.

import {Field, Form} from 'formwood';

Example

const Input = Field(
  class extends React.Component {
    render() {
      return <input {...this.props.element}/>;
    }
  }
);

class MyForm extends React.Component {
  render() {
    return (
      <Form>
        <Input name="email" type="email"/>
        <Input name="password" type="password" validators={[minLength(6)]}/>
      </Form>
    );
  }
}

More Examples

https://ericvaladas.github.io/formwood-examples

Field and Form

Field is a higher order component that will add the necessary functionality to your form fields. You must create a component for your input and then wrap the component with Field. Then, spread this.props.element on your input element. Lastly, use the Form component in place of a form tag when building your form.

Spreading this.props.element on the input element will add all your props, such as name and type, as well as an onChange and defaultValue prop. The onChange handler will store the value of the input in its state, which is later used for form values and validation. The defaultValue prop will set the input with an initial value provided by the Form.

Note: name is a required prop as it is the lookup key for the field's value.

Form submission

When a form is submitted, all fields will have their validators run. The onSubmit event handler is passed an object containing the form's validity and its values.

class MyForm extends React.Component {
  handleSubmit(form) {
    if (form.valid) {
      console.log('Form values:', form.values);
    }
  },

  render() {
    return (
      <Form onSubmit={this.handleSubmit}>
        <Input name="username" type="text"/>
      </Form>
    );
  }
}

Initial Values

You can pass initial values to your fields by adding the values prop to the Form.

class MyForm extends React.Component {
  render() {
    const values = {
      firstName: 'Eric',
      lastName: 'Valadas'
    };

    return (
      <Form values={values}>
        <Input name="firstName" type="text"/>
        <Input name="lastName" type="text"/>
      </Form>
    );
  }
}

Validators

Validators are simply functions that return an error message.

function minLength(length) {
  return value => {
    if (!value || value.length < length) {
      return `Must be at least ${length} characters`;
    }
  };
}

class MyForm extends React.Component {
  render() {
    return (
      <Form>
        <Input name="username" type="text" validators={[minLength(3)]}/>
      </Form>
    );
  }
}

The validation message will be passed to your field component via the message prop. If a validator does not return a message, it is considered valid.

const Input = Field(
  class extends React.Component {
    render() {
      let className = "form-group";
      if (!this.props.valid) {
        className += " has-error";
      }
      return (
        <div className={className}>
          <label className="control-label" htmlFor={this.props.id}>{this.props.label}</label>
          <input className="form-control" {...this.props.element}/>
          <span className="help-block">{this.props.message}</span>
        </div>
      );
    }
  }
);

Validation

All fields have a validate function that will run through their list of validators. By default, validate is only called when the form is submitted. However, this function is passed down as a prop and can be called whenever you like. Here's an example of validating a field as you type.

const Input = Field(
  class extends React.Component {
    handleChange(e) {
      this.props.element.onChange(e).then(this.props.validate);
    },

    render() {
      return (
        <input {...this.props.element} onChange={e => this.handleChange(e)}/>
      );
    }
  }
);

You can also add field messages to your form which can be useful for things like server-side validation errors after submitting the form.

class MyForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {messages: {}};
  }

  handleSubmit() {
    this.setState({
      messages: {username: 'Username already exists'}
    });
  },

  render() {
    return (
      <Form messages={this.state.messages} onSubmit={this.handleSubmit}>
        <Input name="username" type="text"/>
      </Form>
    );
  }
}

Nested Components

The Form component uses a form prop to provide field registration functions, initial values, and messages to its child components. However, if you want to nest a Field component inside another component, you will need to pass the form prop manually.

class MyComponent extends React.Component {
  render() {
    return <Input name="username" type="text" form={this.props.form}/>
  }
}

class MyForm extends React.Component {
  render() {
    <Form>
      <MyComponent/>
    </Form>
  }
}

API

Form

You can obtain a Form instance by adding a ref prop to your form.

render() {
  return (
    <Form ref={(form) => { this.form = form; }}>
      ...
    </Form>
  );
}
PropertyTypeReturnsDescription
fieldsobjectobject{fieldName: [field, ...], ...}
getCheckboxValues(fieldName)functionArrayAn array of field values
getField(fieldName)functionField instanceThe most recently changed field for the given name
handleSubmit(e)functionPromiseCalls validate then calls props.onSubmit
invalidFieldsobjectobject{fieldName: field, ...}
validate()functionPromiseCalls validate on all fields
values()functionobject{fieldName: fieldValue, ...}
PropDescription
onSubmitPasses an additional form object argument to your handleronSubmit(e, {valid: [bool], values: {...}}
valuesAn object that contains values for the form's fields
messagesAn object that contains messages for the form's fields

Field

These properties are passed down to your field via props.

PropertyTypeReturnsDescription
handleChange(e)functionPromiseSets the value property of the state
validate()functionbooleanCalls each validator and sets the valid and message properties of the state
PropDescription
elementContains essential props (listed below) and any prop you pass to your field
element.defaultCheckedThe initial checked value for the element
element.defaultValueThe initial value for the element
element.onChangeThe field's handleChange function
messageThe message returned by a validator or a form's messages prop
validThe valid property in the field's state. The initial value is true
validateThe field's validate function
validatorsAn array of validators
valueThe value property in the field's state

Note: name is a required prop that you must pass to your field as it is the lookup key for the field's value.

1.7.2

6 years ago

1.7.1

6 years ago

1.7.0

6 years ago

1.6.0

6 years ago

1.5.5

7 years ago

1.5.4

7 years ago

1.5.3

7 years ago

1.5.2

7 years ago

1.5.1

7 years ago

1.5.0

7 years ago

1.4.2

7 years ago

1.4.1

8 years ago

1.4.0

8 years ago

1.3.2

8 years ago

1.3.1

8 years ago

1.3.0

8 years ago

1.1.4

8 years ago

1.1.3

8 years ago

1.1.2

8 years ago

1.1.1

8 years ago

1.1.0

8 years ago

1.0.2

8 years ago

1.0.0

8 years ago

0.9.0

8 years ago

0.8.0

8 years ago

0.7.2

8 years ago

0.6.0

8 years ago

0.5.1

8 years ago

0.4.1

8 years ago

0.4.0

8 years ago

0.2.0

8 years ago

0.1.2

8 years ago

0.0.14

8 years ago

0.0.13

8 years ago

0.0.10

8 years ago

0.0.8

8 years ago

0.0.7

8 years ago

0.0.5

8 years ago

0.0.4

8 years ago

0.0.3

8 years ago

0.0.2

8 years ago

0.0.1

8 years ago