formwood v1.7.2
Formwood
A small library for building forms and validation with React.
Usage
Install the package with npm.
npm install --save formwoodImport 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>
);
}| Property | Type | Returns | Description |
|---|---|---|---|
fields | object | object | {fieldName: [field, ...], ...} |
getCheckboxValues(fieldName) | function | Array | An array of field values |
getField(fieldName) | function | Field instance | The most recently changed field for the given name |
handleSubmit(e) | function | Promise | Calls validate then calls props.onSubmit |
invalidFields | object | object | {fieldName: field, ...} |
validate() | function | Promise | Calls validate on all fields |
values() | function | object | {fieldName: fieldValue, ...} |
| Prop | Description |
|---|---|
onSubmit | Passes an additional form object argument to your handleronSubmit(e, {valid: [bool], values: {...}} |
values | An object that contains values for the form's fields |
messages | An object that contains messages for the form's fields |
Field
These properties are passed down to your field via props.
| Property | Type | Returns | Description |
|---|---|---|---|
handleChange(e) | function | Promise | Sets the value property of the state |
validate() | function | boolean | Calls each validator and sets the valid and message properties of the state |
| Prop | Description |
|---|---|
element | Contains essential props (listed below) and any prop you pass to your field |
element.defaultChecked | The initial checked value for the element |
element.defaultValue | The initial value for the element |
element.onChange | The field's handleChange function |
message | The message returned by a validator or a form's messages prop |
valid | The valid property in the field's state. The initial value is true |
validate | The field's validate function |
validators | An array of validators |
value | The 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.
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago