# react-form-helper-sl

> Make creating react forms easier. It handles state, validation and async submission

Latest version **0.0.5** (published 2017-04-12) · ISC license · 0 weekly downloads

## Install

```sh
npm install react-form-helper-sl
pnpm add react-form-helper-sl
yarn add react-form-helper-sl
bun add react-form-helper-sl
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.5 |
| Published | 2017-04-12 |
| First published | 2017-03-13 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 3 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Taavi Sangel |
| Maintainers | tafkanator |
| Keywords | react, react-compoent, react-form, form |

## Links

- npm: https://www.npmjs.com/package/react-form-helper-sl
- Repository: https://github.com/tafkanator/react-form-helper
- Homepage: https://github.com/tafkanator/react-form-helper#readme
- Issues: https://github.com/tafkanator/react-form-helper/issues
- npm.io page: https://npm.io/package/react-form-helper-sl

## Dependencies (3)

- [react](https://npm.io/package/react.md) ^15.4.2
- [react-dom](https://npm.io/package/react-dom.md) ^15.4.2
- [immutability-helper](https://npm.io/package/immutability-helper.md) ^2.1.2

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.0.5 (latest) — 2017-04-12
- 0.0.2 (alpha) — 2017-03-13
- 0.0.4 — 2017-03-17
- 0.0.3 — 2017-03-13
- 0.0.1 — 2017-03-13

## README

# React form

A very simple and lightweight library to help build forms in React faster:
* manages form state by itself
* helps with field validation (client and server side)
* helps with async form submitting

```javascript
import React from 'react';
import { Form, Field } from 'react-form-helper-sl';

const Form = () => (
	<Form onSubmit={(values) => { /* { firstName: '', lastName: '' } */ }}>
		<Field name="firstName" />
		<Field name="lastName" />

		<button type="submit">Submit</submit>
	</Form>
);

export default Form;
```

## Table of contents

* [Components](#components)
* [How validation works](#how-validation-works)
* [Examples](#examples)


## Components

### `<Form />`
This is for wrapping all form. It stores all form state. It also gives callbacks for `onSubmit`, `onSuccess` and `onError`

#### possible values
```javascript
<Form
	className="form"
	onSubmit={(values) => { /* return promise, object with errors, true, false or nothing here */ }}
	onSuccess={(reset) => { reset(); /* reset form values */ } }
	onFail={(e) => { return e.validationErrors; /* return object where key is field name and value is error message */ } }
>
	children
</Form>
```

### `<Field />`
A single input. It can be any input or even custom component.

| Prop | description | default |
|------|-------------|---------|
| name | used as a key for storing value. This field is required and have to be unique |
| type | any input type eg: `number`, `range`, `email`, `textarea`, `checkbox`, `radio`, `select` ... | text
| defaultValue | initial field value | ""
| defaultChecked | initial field value for checkbox | false
| label | if provided, will render html `<label>`
| options | if type is `select`, then you need to provide options as an array of objects, where object key is value and and object value is label. eg `[{ value1: 'Value 1' }]`
| className | css class. If default renderer is used, it will generate following classNames: `field`, `field--has-errors`, `field__input`, `field__error`. If className is provided, `field` will be replaced | field |
| validate | callback for validating input value. Can be function or array of functions. Function must return error string or `undefined` |
| component | This is used for rendering custom JSX instead default one. It gives two sets of parameters: input - required for making state updating to work,  props - error, isTouched, className and any other custom parameter defined in `<Field />` |
| onChange | callback whenever input value changes. it gives tow parameters: `event` and `validate(fieldName)`. validate can be used to trigger validation for another field |
| onBlur | callback whenever input is blurred. It gives one parameter: `event` |

#### possible values
```javascript
<Field
	name="requiredString"
	type="number"
	className="my-input"
	defaultValue={7}
	options={[{ option1: 'Option 1' }, { option1: 'Option 1' }]} // only used if type="select"
	component={(input, props) => {}}
	validate={(name, values) => values[name] < 1 && 'Has to be positive integer'}
	transform={value => parseInt(value, 10)}
	{...customProps}
/>
```

#### example
```javascript
// If using custom component, it is possible to inject any property to component

const renderInput = (input, {label, error, isTouched}) => (
	<div>
		<label for={`input-${input.name}`}>{label}</label>
		<input {...input} id={`input-${input.name}` />
		{isTouched && error && (<span>{error}</span>)}
	</div>
);

const Form = () => (
	<Form onSubmit={(values) => { /* do something with values */ }}>
		<Field name="firstName" label="First name" component={renderInput} />
		<Field name="lastName" label="Last name" component={renderInput} />

		<button type="submit">Submit</submit>
	</Form>
);
```


## `<WithFormProp />`
A way to render something conditionally based on current form state. It's basically a higher order component inside JSX.

| Prop | description |
|------|-------------|
| isSubmitting | true if form `onSubmit` is resolving promise |
| hasErrors | true if any field has errors |
| component |  This is used for rendering custom JSX instead default one. It gives a object with parameters: `isSubmitting`, `hasErrors` |

There are two ways to use it:

```javascript
// renders only if isSubmitting is true.
<WithFormProp isSubmitting>
	<p>Please wait</p>
</WithFormProp>
// Note that condition can also be negative. eg isSubmitting={false}
```

```javascript
// use form props directly
<WithFormProp
	component={({ hasErrors, isSubmitting }) => (
		<button className="btn" type="submit" disabled={isSubmitting || hasErrors}>Send</button>
	)}
/>
```

```javascript
// possible values
<WithFormProp isSubmitting hasErrors={false} component={(values) => {}}>
	children
</WithFormProp>
```

## How validation works

* if field has been touched (input has been blurred at least once or user has tried to submit form), every time value is changed, it will validate itself.
* whenever form is submitted, all validations are run, and if no errors are found, `onSubmit` will be called
* if `onSubmit` returns false, `onError` is called. If promise is returned, it will resolve it, otherwise `onSuccess` is called


## Examples
[Full example can be found here](examples/App.js)

### Custom Field renderer

```javascript
// ...

const renderSelect = (input, { error, isTouched, className }) => (
	<div className={className}>
		<select {...input} className={`${className}__input`}>
			<option value="18-">&lt; 18</option>
			<option value="18-50">18-50</option>
			<option value="50+">&gt; 50</option>
		</select>

		{isTouched && error && (
			<span className={`${className}__error`}>{error}</span>
		)}
	</div>
);

const Form = () => (
	<Form onSubmit={(values) => { /* do something with values */ }}>
		<Field name="age" component={renderSelect} defaultValue="18-" />

		<button type="submit">Submit</submit>
	</Form>
);

// ...
```

### Form validation

First name has to be defined. Last name have to be at least 5 characters long. IF checkbox is checked, email must be defined.
```javascript
// ...

export const required = (name, values) => (values[name] ? undefined : 'Field is required');

const minLength = min => (name, values) =>
	(values[name] && values[name].length < min ? `Must be at least ${min} characters` : undefined);

const requiredIfHasField = fieldName => (name, values) =>
	(values[fieldName] && !values[name] ? 'Field is required' : undefined);

const Form = () => (
	<Form onSubmit={(values) => { /* do something with values */ }}>
		<Field name="firstName" validate={required} />
		<Field name="lastName"  validate={[required, minLength(5)]} />
		<Field type="email" name="email" validate={requiredIfHasField('subscribeToEmail')} />
		<Field type="checkbox" name="subscribeToEmail" onChange={(e, validate) => { validate('email'); }} />

		<button type="submit">Submit</submit>
	</Form>
);

// ...
```

## RUNNING EXAMPLES
* download project:
* run `npm install`
* run `npm start`
* open browser at [localhost:3000](http://localhost:3000)

## TODO
- [ ]  travis integration
- [ ]  tests
- [ ]  improve documentation
- [ ]  better bundle files

---
_Source: https://npm.io/package/react-form-helper-sl · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
