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 🙏

© 2026 – Pkg Stats / Ryan Hefner

form-functionality-library

v1.9.5

Published

A modular, flexible form functionality library for Webflow forms supporting single-step, multi-step, and branching forms

Readme

Form Functionality Library

A modular, flexible form functionality library designed to add advanced functionality to Webflow forms, supporting single-step forms, multi-step forms, and multi-step forms with logic branching.

Features

  • Single-step forms - Enhanced validation and error handling
  • Multi-step forms - Step-by-step navigation with progress tracking
  • Multi-step forms with logic branching - Conditional step display based on user input
  • Real-time validation - Field validation with custom error messages
  • Summary generation - Automatic summary display with flexible formatting
  • State management - In-memory state management for performance
  • Data-attribute driven - No binding to classes or IDs
  • TypeScript - Fully typed with comprehensive JSDoc documentation
  • Verbose logging - Detailed console output for debugging

Quick Start

1. Include the Library

<!-- Load from jsDelivr (when published) -->
<script type="module">
  import FormLib from 'https://cdn.jsdelivr.net/npm/form-functionality-library@latest/dist/index.js';
</script>

2. Set Up Your HTML

<form data-form="multistep" data-logic="true">
  <!-- Step 1 -->
  <div data-form="step" data-answer="step-1">
    <input type="text" name="firstName" data-step-field-name="firstName" required>
    <select name="role" data-step-field-name="role" data-go-to="manager-step">
      <option value="Manager">Manager</option>
      <option value="Employee">Employee</option>
    </select>
  </div>
  
  <!-- Conditional Step (only shows if role = Manager) -->
  <div data-form="step" data-answer="manager-step">
    <input type="text" name="department" data-step-field-name="department" required>
  </div>
  
  <!-- Summary -->
  <div data-summary-field="firstName" data-join="space"></div>
  
  <!-- Navigation -->
  <button data-form="back-btn">Back</button>
  <button data-form="next-btn">Next</button>
  <button data-form="submit">Submit</button>
</form>

3. Initialize (Optional)

The library auto-initializes when it detects compatible forms. For manual control:

// Manual initialization
FormLib.init();

// Check current state
FormLib.logCurrentState();

// Validate form
const isValid = FormLib.validateForm();

// Reset form
FormLib.resetForm();

Data Attributes Reference

Form Configuration

| Attribute | Description | Example | |-----------|-------------|---------| | data-form="multistep" | Marks form as multi-step | <form data-form="multistep"> | | data-logic="true" | Enables branching logic | <form data-logic="true"> |

Steps

| Attribute | Description | Example | |-----------|-------------|---------| | data-form="step" | Marks element as a step | <div data-form="step"> | | data-answer="step-id" | Step identifier for branching | <div data-answer="manager-step"> | | data-step-type="type" | Step categorization | <div data-step-type="manager"> | | data-step-subtype="subtype" | Step sub-categorization | <div data-step-subtype="details"> | | data-step-number="1" | Step numbering | <div data-step-number="1"> |

Navigation

| Attribute | Description | Example | |-----------|-------------|---------| | data-form="next-btn" | Next button | <button data-form="next-btn"> | | data-form="back-btn" | Back button | <button data-form="back-btn"> | | data-form="submit" | Submit button | <button data-form="submit"> | | data-skip="step-id" | Skip to specific step | <button data-skip="summary"> |

Branching Logic

| Attribute | Description | Example | |-----------|-------------|---------| | data-go-to="step-id" | Defines branch target | <input data-go-to="manager-step"> |

Field Configuration

| Attribute | Description | Example | |-----------|-------------|---------| | data-step-field-name="name" | Field identifier for state management | <input data-step-field-name="firstName"> | | data-error-message="text" | Custom error message | <input data-error-message="Name is required"> |

Summary Display

| Attribute | Description | Example | |-----------|-------------|---------| | data-summary-field="field1\|field2" | Fields to display (pipe-separated) | <div data-summary-field="firstName\|lastName"> | | data-join="type" | How to join multiple values | <div data-join="space"> | | data-summary-type="type" | Summary categorization | <div data-summary-type="manager"> |

Join Types

  • space - Join with spaces: "John Doe"
  • comma - Join with commas: "John, Doe"
  • dash - Join with dashes: "John - Doe"
  • pipe - Join with pipes: "John | Doe"
  • newline - Join with line breaks

API Reference

Main FormLib Object

// Initialize library
FormLib.init(rootElement?)

// Check initialization status
FormLib.isInitialized()

// Get current state
FormLib.getState()

// Log current state to console
FormLib.logCurrentState()

// Validate entire form
FormLib.validateForm()

// Reset form to initial state
FormLib.resetForm()

// Get form data
FormLib.getFormData()

// Set form data
FormLib.setFormData(data)

// Destroy library
FormLib.destroy()

Individual Modules

// Import individual modules for advanced usage
import { 
  FormState,
  initBranching,
  initMultiStep,
  initValidation,
  initErrors,
  initSummary
} from 'form-functionality-library';

// FormState management
FormState.setField('fieldName', 'value');
FormState.getField('fieldName');
FormState.getAll();
FormState.clear();

// Validation
validateField('fieldName');
validateStep('stepId');
validateAllVisibleFields();

// Errors
showError('fieldName', 'Error message');
clearError('fieldName');
clearAllErrors();

// Summary
updateSummary();
clearSummary();

Examples

Basic Multi-Step Form

<form data-form="multistep">
  <div data-form="step">
    <h2>Step 1</h2>
    <input type="text" name="name" data-step-field-name="name" required>
  </div>
  
  <div data-form="step">
    <h2>Step 2</h2>
    <input type="email" name="email" data-step-field-name="email" required>
  </div>
  
  <button data-form="back-btn">Back</button>
  <button data-form="next-btn">Next</button>
  <button data-form="submit">Submit</button>
</form>

Branching Logic Form

<form data-form="multistep" data-logic="true">
  <div data-form="step">
    <select name="userType" data-step-field-name="userType" data-go-to="business-step">
      <option value="personal">Personal</option>
      <option value="business">Business</option>
    </select>
  </div>
  
  <!-- Only shows when userType = "business" -->
  <div data-form="step" data-answer="business-step">
    <input type="text" name="company" data-step-field-name="company" required>
  </div>
</form>

Summary Display

<!-- Display first name and last name joined with space -->
<div data-summary-field="firstName|lastName" data-join="space"></div>

<!-- Display manager-specific fields with comma separation -->
<div data-summary-field="department|teamSize" 
     data-join="comma" 
     data-summary-type="manager"></div>

Browser Support

  • Chrome 80+
  • Firefox 72+
  • Safari 13+
  • Edge 80+

Development

Building

# Install dependencies (if using npm)
npm install typescript

# Compile TypeScript
npx tsc

# Output will be in ./dist/

Project Structure

/
├── config.ts              # Configuration constants
├── index.ts               # Main entry point
├── tsconfig.json          # TypeScript configuration
├── /modules/
│   ├── utils.ts           # Shared utilities
│   ├── formState.ts       # State management
│   ├── branching.ts       # Branching logic
│   ├── multiStep.ts       # Multi-step navigation
│   ├── validation.ts      # Form validation
│   ├── errors.ts          # Error handling
│   └── summary.ts         # Summary generation
├── index.html             # Test/demo page
└── README.md

Debugging

The library provides verbose console logging when DEBUG is enabled (default):

// Enable/disable debug logging
DEFAULTS.DEBUG = true; // or false

// Log current state
FormLib.logCurrentState();

// Get detailed state information
const state = FormLib.getState();
console.log(state);

License

MIT License - feel free to use in commercial and personal projects.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

Support

For issues and questions:

  • Check the console for detailed logging
  • Use FormLib.logCurrentState() to debug
  • Review the data attributes in your HTML
  • Ensure proper TypeScript compilation