hanzo-form

Form.js is a lightweight browser library for automatic form validation and submission.

Hanzo Form.js - Automatic Form Validation and Submission

Category: Hanzo Ecosystem Related Skills: hanzo/hanzo-checkout.md, hanzo/hanzo-commerce.md

Overview

Form.js is a lightweight browser library for automatic form validation and submission. It intercepts native HTML form submit events, emits lifecycle events (init, submit, done), and provides an XHR helper for posting form data as JSON. Zero dependencies beyond little-emitter. Written in CoffeeScript, ships as both CommonJS and ES module bundles. Designed as a companion to Hanzo's mailing list and lead capture forms.

Tech Stack

OSS Base

Repo: github.com/hanzoai/form.js (branch: master, 16 stars).

When to use

Hard requirements

  1. Browser environment with DOM (not Node.js server-side)
  2. HTML <form> element in the page -- the library auto-discovers the last form on the page at load time
  3. Script tag must be inside or after the form (uses getElementsByTagName to find the last <script> and <form>)

Quick reference

| Item | Value | |------|-------| | npm package | form.js | | Version | 0.2.0 | | Default branch | master | | License | BSD-3-Clause | | Language | CoffeeScript | | CJS entry | lib/form.cjs.js | | ES entry | lib/form.es.js | | Global | window.Inform | | Runtime dep | little-emitter only | | Repo | github.com/hanzoai/form.js |

One-file quickstart

Script tag integration

<form action="/subscribe" method="POST">
 <input type="email" name="email" placeholder="Email" required />
 <input type="text" name="firstName" placeholder="First Name" />
 <button type="submit">Subscribe</button>

 <script src="https://unpkg.com/[email protected]/lib/form.cjs.js"></script>
 <script>
 var Inform = window.Inform

 // Listen for form submission (prevents default, gives you control)
 Inform.on('inform-submit', function(done, event) {
 var formData = new FormData(event.target)
 var data = {}
 formData.forEach(function(value, key) { data[key] = value })

 fetch('/api/subscribe', {
 method: 'POST',
 headers: { 'Content-Type': 'application/json' },
 body: JSON.stringify(data)
 })
 .then(function() { done() }) // Call done() to fire the 'done' event
 .catch(function(err) { console.error(err) })
 })

 // Listen for successful submission
 Inform.on('inform-done', function(event) {
 alert('Thanks for subscribing!')
 })
 </script>
</form>

npm install

npm install form.js
// ES module
import Inform from 'form.js'

Inform.on('inform-submit', function(done, event) {
 // Handle submission
 done()
})

Core Concepts

Architecture

┌────────────────────────────────────────┐
│ HTML Page │
│ │
│ <form> │
│ <input name="email" /> │
│ <button type="submit">Go</button> │
│ │
│ <script src="form.js"></script> │
│ </form> │
│ │
│ ┌──────────────────────────────────┐ │
│ │ Inform (EventEmitter) │ │
│ │ │ │
│ │ Events: │ │
│ │ 1. init-inform-script ─────> script tag ref │
│ │ 2. init-inform-form ─────> form element ref │
│ │ 3. init-inform-inputs ─────> input elements │
│ │ 4. init-inform-submits ─────> submit buttons │
│ │ 5. inform-submit ─────> (done, event) │
│ │ 6. inform-done ─────> completion │
│ └──────────────────────────────────┘ │
└────────────────────────────────────────┘

Event Lifecycle

  1. DOM ready -- Library auto-initializes, finds the last <form> and <script> tags
  2. init-inform-script -- Fires with the script element reference
  3. init-inform-form -- Fires with the form element reference
  4. init-inform-inputs -- Fires with array of input/select elements (excludes submit buttons)
  5. init-inform-submits -- Fires with array of submit buttons (input[type=submit] + button[type=submit])
  6. inform-submit -- Fires on form submit with (done, event). Call done() to proceed to inform-done. The default form submit is prevented.
  7. inform-done -- Fires after done() is called, re-dispatches the native submit event

Global API

The library exposes window.Inform as an event emitter with standard methods:

XHR Helper (src/xhr.coffee)

A minimal XMLHttpRequest wrapper with a post(url, headers, payload, callback) method. Used internally for legacy AJAX form submission. Supports IE via ActiveXObject fallback.

Source Files

| File | Purpose | |------|---------| | src/index.coffee | Main library: auto-init, event lifecycle, form interception | | src/xhr.coffee | XHR POST helper class |

Directory structure

form.js/
 package.json # npm config, v0.2.0
 Cakefile # Build/test tasks (shortcake + cake-bundle)
 README.md # Minimal README
 LICENSE # BSD-3-Clause
 .travis.yml # Travis CI config
 src/
 index.coffee # Main library (event emitter + form interception)
 xhr.coffee # XMLHttpRequest POST helper
 test/
 test.coffee # Selenium WebDriver integration tests
 test.html # Test harness HTML page
 inform.js # Built test bundle
 util.coffee # Test utilities
 ci-config.coffee # Cross-browser Sauce Labs config
 jquery-1.11.3.min.js # jQuery for test assertions
 lib/ # Built output (generated)
 form.cjs.js # CommonJS bundle
 form.es.js # ES module bundle

Build and Test

# Install dependencies
npm install

# Build (generates lib/form.cjs.js and lib/form.es.js)
cake build

# Run tests (starts static server + Selenium + Mocha)
cake test

# Clean build artifacts
cake clean

Troubleshooting

| Issue | Cause | Solution | |-------|-------|----------| | window.Inform is undefined | Script loaded before form.js bundle | Ensure form.js script tag is loaded | | Form submits normally (page reload) | Script tag not inside/after the form | Place <script> inside the <form> or after it | | inform-submit not firing | Form has no submit button | Add <button type="submit"> or <input type="submit"> | | Events fire twice | DOMContentLoaded and load both trigger init | Library guards against double-init internally | | done() not working | Not calling the first argument of inform-submit callback | Signature is function(done, event) -- call done() to proceed |

Related Skills


Last Updated: 2026-03-13 Category: Hanzo Ecosystem Related: forms, validation, submission, lead-capture, mailing-list Prerequisites: Browser environment, HTML form element