Socket
Socket
Sign inDemoInstall

rich-forms

Package Overview
Dependencies
0
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    rich-forms

A framework agnostic library for modeling complex data in HTML forms.


Version published
Maintainers
1
Created

Readme

Source

Rich Forms

A simple, framework-agnostic form-processing library for front-end applications.

Have you ever tried to make a form to input an array of Addresses? It's was a pain, right? Modeling nested arrays and objects in HTML forms tends to be. rich-forms allows you to parse a key-value based FormData object into a rich, nested object.

It uses the name attribute of the form elements to index into the final object.

Installation

npm install rich-forms

Example Usage

<form>
	<input type="text" name="name" />
	<input type="text" name="address.street" />
	<input type="text" name="address.city" />
	<input type="text" name="address.zip" />
</form>
import { parse } from "rich-forms";
const form = document.querySelector("form");
const formData = new FormData(form);
const data = parse(formData);
console.log(data);
/* 
{ 
    name: 'John Doe', 
    address: { 
        street: '123 Main St', 
        city: 'Anytown', 
        zip: '12345' 
    }
}
*/

It also integrates very well with component libraries like Svelte and Vue.

<script>
    import { parse } from "rich-forms";

    function handle_submit(event) {
        event.preventDefault();
        const form = event.target;
        const formData = new FormData(form);
        const data = parse(formData);
        console.log(data); // { addresses: [ {street: '123 Main St', city: 'Anytown', zip: '12345'}] }
    }

    let address_fields = [{id: 0}];

    function add_address() {
        address_fields.push({ id: Math.random() })
        address_fields = address_fields
    }

    function remove_address(id) {
        address_fields = address_fields.filter(f => f.id !== id)
    }
</script>

<form on:submit={handle_submit}>
    {#each address_fields as field, i (field.id)}
        <fieldset>
            <legend>Address {i}</legend>
            <input type="text" name="addresses[{i}].street" />
            <input type="text" name="addresses[{i}].city" />
            <input type="text" name="addresses[{i}]zip" />
            <button type="button" on:click={()=>remove_address(field.id)}>Remove Address</button>
        </fieldset>
    {/each}
    <button type="button" on:click={add_address}>Add Address</button>
    <button>Submit</button>
</form>

Rich-Forms only gives you the raw objects / arrays, it does not provide any validation. We recommend using a schema-validation library like Zod to validate the data.

This could look something like this:

import { parse } from "rich-forms";
import { z } from "zod";

const AddressSchema = z.object({
	street: z.string(),
	city: z.string(),
	zip: z.string()
});

const UserSchema = z.object({
	name: z.string(),
	addresses: z.array(AddressSchema)
});

const form = document.querySelector("form");
const formData = new FormData(form);

try {
	const data = parse(formData);
	const user = UserSchema.parse(data); // Validates that the Data has the correct shape. Returned object is typed.
} catch (error) {
	//Handle invalid data
}

Syntax

The path of a form-elements value is determined by it's name attribute. You can write paths the same way you would in JavaScript.

  • Use . to index into an object
  • Or Use [0] to index into an object

Using only numbers to index into an object will result in an array being created.

<form>
	<input type="text" name="name" />
	<input type="text" name="addresses[0].street" />
	<input type="text" name="addresses[0].city" />
	<input type="text" name="addresses[0].zip" />
	<input type="text" name="addresses[1].street" />
	<input type="text" name="addresses[1].city" />
	<input type="text" name="addresses[1].zip" />
</form>

Becomes

{
    name: 'John Doe',
    addresses: [
        {
            street: '123 Main St',
            city: 'Anytown',
            zip: '12345'
        },
        {
            street: '123 Main St',
            city: 'Anytown',
            zip: '12345'
        }
    ]
}

API

You can pass a FormData object, or an HTMLFormElement to the parse function.

Additionally, you can optionally pass an options object as the second argument.

//Default options shown
parse(formData, {
    populate_arrays: true,
    populate_booleans: true,
    duplicates_as_array: false; //If you have inputs with `multiple` set, then set this to true
})

If invalid syntax is used in the name attribute, a SyntaxError will be thrown.

Keywords

FAQs

Last updated on 17 Apr 2023

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc