npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

formsquare

v1.0.0-beta.3

Published

Serialize html5 forms the smart way

Downloads

264

Readme

npm Build Status Coverage Status

formsquare

Turn your HTML5 forms into javascript objects the smart way.

Installation

npm install --save formsquare

Usage

Module

import formsquare from "formsquare";

formsquare.parse(form);

// or
formsquare.filter(myFilter).parse(form);

Where form is an HTMLFormElement (like document.forms[0]) and myFilter is a predicate function (like el => !el.disabled) that determines which form elements to include.

commonjs

Same as above except import with:

const formsquare = require("formsquare");

HTML

Download the full script or minified script and include this in your HTML file:

<script src="formsquare.js"></script>
<script>
  formsquare.parse(document.forms[0]);
</script>

Or download the module and import it:

<script module>
  import formsquare from "/path/to/module/formsquare.js";

  formsquare.parse(document.forms[0]);
</script>

More examples below

What makes formsquare different

Formsquare is yet another square bracket notation form to javascript object parser, but smarter. Formsquare tries to be smart about your form structure and keep open most possible mappings to valid JSON objects. Formsquare will also take note of your HTML5 form attributes, even in Internet Explorer.

For the first part formsquare tries to retain the types of your form elements.

  • Inputs of type checkbox with no explicit value attribute get the value true if it is checked, and false otherwise.
  • Inputs of type number and range gets it value casted to number.
  • Inputs of type month, week, date, and datetime-local will get their values as a Date object. Invalid dates, retain their original values.
  • All other elements get their value as string.

Secondly formsquare won’t force you into a root object.

  • Form elements with explicit name attribute will nest inside an object.
  • Form elements with a name starting with [] will nest inside an array.
  • Form elements without an explicit name will either be a single value (if it is the only element of the form) or an array.

And finally formsquare tries retain the meaning of your checkboxes.

  • A single valued checkbox will be that value if checked, otherwise it will be null.
  • A collection (2 or more) of valued checkboxes, sharing the name, will collect all checked values into an array.
  • Explicit array checkboxes will always be collected in an array if checked.

This means that you’ll now have more flexeble options in structuring your HTML forms. If your form only takes a single number, just leave an unamed input of type number.

Examples

Basic usage

<form id="my-form">
  <input name="foo" value="bar">
  <input name="baz" value="quux" disabled>
</form>
import formsquare from "formsquare";

const form = document.getElementById("my-form");
const filter = el => !el.disabled;

formsquare.filter(filter).parse(form);
//=> {"foo": "bar"}

Filters

You can call formsquare.filter with a predicate be returned a new parser that will filter all form elements by that predicate.

<form>
  <input value="foo">
  <input value="bar" disabled>
</form>

<form>
  <input value="foo" disabled>
  <input value="bar">
</form>

<form>
  <input value="foo" disabled>
  <input value="bar" class="hidden">
  <input value="baz">
</form>
import formsquare from "formsquare";

const { parse } = formsquare.filter(el => !el.disabled);

parse(document.forms[0]);
//=> "foo"

parse(document.forms[1]);
//=> "bar"

// Filters can be chained

formsquare
  .filter(el => !el.disabled)
  .filter(el => !el.classList.contains("hidden"))
  .parse(document.forms[2]);
//=> "baz"

Simple forms

An empty form will always return null

<form id="empty-form"></form>
formsquare.parse(document.getElementById("empty-form"));
//=> null

A form with a single element without an explicit name gives you a singleton value.

<form id="singleton-form">
  <input type="number" value="42">
</form>
const singletonForm = document.getElementById("singleton-form");
formsquare.parse(singletonForm);
//=> 42

singletonForm[0].type = "text";
formsquare.parse(singletonForm);
//=> "42"

Collections of forms

You can pass in an array or a [node list][mdn#node-list] of forms and it will be handled as a single form.

<form>
  <input type="number" name="foo" value="2">
  <input type="number" name="bar" value="5">
</form>

<form>
  <input type="number" name="foo" value="42">
</form>
formsquare.parse(document.forms);
//=> {"foo": [2, 42], "bar": 5}

[...document.forms].map(formsquare.parse);
//=> [{"foo": 2, "bar": 5}, {"foo": 42}]

Checkboxes

If your form needs a list of booleans, you only need to omit the value attribute:

<form id="checkbox-form">
  <input type="checkbox" name="[]">
  <input type="checkbox" name="[]" checked>
</form>
const checkboxForm = document.getElementById("checkbox-form");
formsquare.parse(checkboxForm);
//=> [false, true]

Checkboxes with explicit values are handled differently:

checkboxForm[0].value = "false";
checkboxForm[1].value = "on";

formsquare.parse(checkboxForm);
//=> ["on"]

And if no checkbox is checked, you will get the empty array:

checkboxForm[1].checked = false;

formsquare.parse(checkboxForm);
//=> []

Files

Inputs with the type of “file” (<input type="file">) result in a promise containing the file object. File inputs with multiple set to true will result in promise of an array of such objects.

<form>
  <input type="file">
</form>

Granted that a user uploaded the file foo.txt conatining the text foo:

await formsquare.parse(document.forms[0]);

//=> {
//     body: "Zm9v",
//     name: "foo.txt",
//     type: "text/plain",
//   }

Alternatives

If you want a more traditional form parser, you could take a look at any of these: