Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/chrisfrank/uninformed

Nostalgically simple forms for React and Preact
https://github.com/chrisfrank/uninformed

ajax-form forms preact react uncontrolled-components

Last synced: about 1 month ago
JSON representation

Nostalgically simple forms for React and Preact

Awesome Lists containing this project

README

        

# Uninformed

Nostalgically simple forms for React and Preact.

```
npm install uninformed
```

You’ll also need either React >= 16 or Preact >= 8.

## Why?

Forms in Rails do two useful things by default:

- [x] Send data to the server without refreshing the page
- [x] Prevent accidental double-submissions

Uninformed is a tiny library that brings these defaults to the React/Preact
ecosystem.

## Getting Started

```jsx
import { Form } from 'uninformed';
import React from 'react';

export const SignupForm = () => (




)
```

That’s it! No `onChange` handlers, no `render` props, just a lightly-enhanced
HTML form that disables itself on submit, sends data to a server via AJAX, and
re-enables itself after the server responds.

- [Basic Props](#basic-props)
- [action](#action)
- [method](#method)
- [enctype / encType](#enctype--enctype)
- [onSubmit](#onsubmit)
- [beforeSend](#beforesend)
- [onSuccess](#onsuccess)
- [onError](#onerror)
- [Advanced Props](#advanced-props)
- [serialize](#serialize)
- [send](#send)
- [Use In Preact](#use-in-preact)
- [Browser Support](#browser-support)
- [Prior Art](#prior-art)
- [Contributing](#contributing)
- [Bugs](#bugs)
- [Pull Requests](#pull-requests)

## Basic Props

### action

> `string` | any valid URI

The URI of the service that will process your form, e.g. `/api/signups`

### method

> `string` | any valid HTTP verb | defaults to `POST`

The HTTP method to use when sending the form data, e.g. `POST`, `PATCH`, etc

### enctype / encType

> `string` | defaults to `application/x-www-form-urlencoded`

The encoding of the Form. Like the standard HTML `enctype` attribute, you can
set this prop to `multipart/form-data` to support file uploads. Unlike the HTML
`enctype` attribute, you can also set this prop to `application/json` to send
JSON. Note that React expects form elements to have a camelCase `encType` prop
instead of `enctype`. Uninformed supports either style and converts to
camelCase internally.

### onSubmit

> `function(event, payload)` | optional

Called when a form is submitted. Use `onSubmit` to perform client-side
validation, trigger updates to your UI, etc. You can return `false` from this
function to prevent your `Form` from submitting.

### beforeSend

> `function(xhr)` | optional

Manipulate your form's
[XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
instance before sending. Use this prop set auth headers, configure CORS, etc:

```jsx
const SignupForm = () => (
{
// include auth credentials
xhr.setRequestHeader("Authorization", `Bearer ${USER_AUTH_TOKEN}`);
// parse response as JSON automatically
xhr.responseType = "json";
// add a pogress meter?
xhr.addEventListener("progress", this.props.onProgressUpdate);
}}
>



);
```

### onSuccess

> `function(xhr)` | optional

Handle a successful form response.

```jsx
const AuthForm = props => (
{
const user = JSON.parse(xhr.responseText);
props.onLogin(user);
}}
>




);
```

### onError

> `function(xhr)` | optional

Handle a failed form response.

```jsx
const AuthForm = () => (
{
const error = JSON.parse(xhr.responseText);
alert(`Error ${xhr.status}: ${error.message}`);
}}
>




);
```

## Advanced Props

### serialize

> `function(HTMLFormElement)`

Use a custom serializer. The built-in serializers for url-encoded and multipart
encodings follow the [qs](https://github.com/ljharb/qs)/Rails standard for
nested object support, but the built-in JSON serializer doesn't support
nested objects. Here's how you could serialize nested JSON with help from
[form-serialize](https://github.com/defunctzombie/form-serialize).

```jsx
import { Form } from "uninformed";
import serialize from "form-serialize";

const SignupForm = () => (
{
const data = serialize(formElement, { hash: true });
// data looks like this:
// {
// user: {
// name: 'abc',
// email: '[email protected]',
// interests: ['Ethics', 'Food'],
// },
// }
return JSON.stringify(data);
}}
>



Ethics
Food



);
```

### send

> `function(payload, formInstance) => promise`

Use a custom function to send your form data, instead of the XMLHttpRequest
Uninformed uses by default. **This function must return a Promise.** Here's an
example that uses the
[Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API):

```jsx
const SignupForm = props => (
{
const { method, action } = formInstance.props;
return fetch(action, {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${props.authToken}`
},
method,
body: payload
}).then(res => res.json());
}}
>



);
```

## Use In Preact

Uninformed is built as a library-agnostic
[factory function](https://github.com/preactjs/preact/issues/408). To use it in
Preact without a preact-compat, import the factory directly:

```jsx
import { createForm } from 'uninformed/dist/factory';
import { h, Component } from 'preact';
const Form = createForm({ h, Component });

export default const SignupForm = () => (




)
```

## Browser Support

Uninformed supports modern browsers and IE11. If you use a custom `send`
function, you will need to
[polyfill Promise support](https://www.npmjs.com/package/promise-polyfill)
in IE.

## Prior Art

- [react-formify - npm](https://www.npmjs.com/package/react-formify)
- [react-uncontrolled-form - npm](https://www.npmjs.com/package/react-uncontrolled-form)
- [react-form-uncontrolled - npm](https://www.npmjs.com/package/react-form-uncontrolled)

None of these libraries handle submitting data or preventing double-submissions,
but they do handle client-side validation.

## Contributing

### Bugs

Please open [an issue](https://github.com/chrisfrank/uninformed/issues) on
Github.

### Pull Requests

PRs are welcome, and I'll do my best to review them promptly.