Now.js Framework Documentation

Now.js Framework Documentation

Form Elements - Overview

EN 04 Sep 2026 01:40

Form Elements - Overview

Complete guide for Form Elements in the Now.js Framework - enhanced input components with validation, formatting, and event handling.

📋 Table of Contents

  1. Overview
  2. Architecture
  3. Quick Start
  4. Element Types
  5. Quick Selection Guide
  6. Common Features
  7. Element Registration
  8. Related Documentation

Overview

Form Elements in Now.js are enhanced input components built on the ElementFactory base class. They provide automatic validation, formatting, state management, and event handling - all configurable via HTML data attributes.

Key Features

  • ✅ Declarative Configuration: Configure via HTML data-* attributes
  • ✅ Auto-Enhancement: Existing HTML inputs are automatically enhanced
  • ✅ Validation System: Built-in and custom validation rules
  • ✅ Formatting: Automatic input/output formatting
  • ✅ State Management: Track valid, modified, error states
  • ✅ Event System: Consistent events across all elements
  • ✅ Wrapper Support: Auto-creates labels, containers, comments
  • ✅ FormManager Integration: Works seamlessly with FormManager

How It Works

HTML Input → ElementManager detects data-element →
Appropriate Factory enhances element → Instance with full API

Architecture

Class Hierarchy

ElementFactory (Base Class)
├── TextElementFactory          # data-element="text"
│   ├── EmailElementFactory     # data-element="email"
│   ├── UrlElementFactory       # data-element="url"
│   └── UsernameElementFactory  # data-element="username"
├── PasswordElementFactory
├── SearchElementFactory
├── NumberElementFactory
│   └── CurrencyElementFactory
├── MaskElementFactory
│   └── TelElementFactory
├── SelectElementFactory
├── MultiSelectElementFactory
├── TextareaElementFactory
├── RichTextElementFactory
├── FileElementFactory
├── DateElementFactory
├── ColorElementFactory
├── RangeElementFactory
└── TagsElementFactory

Core Components

Component Purpose
ElementFactory Base class with validation, state, events
ElementManager Registry and auto-enhancement coordinator
FormManager Form-level validation and submission
FormError Error display and management

Quick Start

Basic HTML Enhancement

Simply add data-element attribute to enable auto-enhancement:

<!-- Text input with autocomplete -->
<input type="text"
       data-element="text"
       data-autocomplete="true"
       data-source="/api/cities"
       name="city"
       placeholder="Select city">

<!-- Number input with formatting -->
<input type="text"
       data-element="number"
       data-precision="2"
       data-use-grouping="true"
       name="price"
       placeholder="0.00">

<!-- Currency input with 4 decimal places -->
<input type="currency"
  step="0.0001"
  data-decimals="4"
  name="unit_cost"
  placeholder="0.0000">

<!-- Password with strength meter -->
<input type="password"
       data-element="password"
       data-strength-meter="true"
       name="password">

<!-- Date picker -->
<input type="text"
       data-element="date"
       data-format="d/m/Y"
       name="birthdate">

<!-- Select with type-to-filter -->
<select data-element="select" name="country">
  <option value="">Select country</option>
  <option value="TH">Thailand</option>
  <option value="US">United States</option>
</select>

JavaScript Access

// Get enhanced instance
const cityInput = document.querySelector('[name="city"]');
const instance = ElementManager.getInstance(cityInput);

// Use instance API
instance.element.value = 'Bangkok';
instance.validate();
console.log(instance.isValid());    // true/false
console.log(instance.isModified()); // true/false

// Listen to events
cityInput.addEventListener('change', (e) => {
  console.log('New value:', e.target.value);
});

Element Types

Quick Reference Table

Type data-element Description Documentation
Text text Text input with autocomplete text-elements.md
Email email Text input with email validation text-elements.md
Url url Text input with URL validation text-elements.md
Username username Text input with username rules text-elements.md
Password password Password with strength meter text-elements.md
Search search Search with debounce text-elements.md
Number number Number with formatting number-elements.md
Currency currency Currency formatting number-elements.md
Select select Enhanced select select-elements.md
MultiSelect select-multiple Multiple selection select-elements.md
Date date Date picker date-elements.md
Datetime datetime-local Date picker with time date-elements.md
File file File upload FileElementFactory.md
Color color Color picker special-elements.md
Range range Range slider special-elements.md
Tags tags Tags/chips input special-elements.md
Mask mask Input masking special-elements.md
Tel tel Phone number special-elements.md
Textarea textarea Auto-resize textarea special-elements.md
RichText richtext Rich text editor special-elements.md

Quick Selection Guide

Which Element Type to Use?

Scenario Element Why
Username/email input text Basic text with validation
Autocomplete from list text + data-autocomplete Has built-in autocomplete
Password entry password Strength meter, toggle visibility
Search box search Debounced input
Price/quantity number Formatting, step controls
Money amount currency Currency formatting
Dropdown selection select Type-to-filter, ajax loading
Multiple choice tags select-multiple Custom multi-select UI
Date/time date Calendar picker
File upload file Drag-drop, preview
Color selection color Color palette picker
Slider value range Single/dual range
List of tags tags Add/remove chips
Phone number tel or mask Auto-formatting
Long text textarea Auto-resize

Common Features

All Form Elements share these common features from ElementFactory:

1. Validation

<!-- Required validation -->
<input data-element="text" required>

<!-- Pattern validation -->
<input data-element="text" pattern="[A-Za-z]+">

<!-- Length validation -->
<input data-element="text" minlength="3" maxlength="50">

<!-- Custom validation rules -->
<input data-element="text" data-validate="required,email">

<!-- Custom error messages -->
<input data-element="text"
       data-validate="required"
       data-error-required="Please enter your email">

2. State Management

const instance = ElementManager.getInstance(element);

// Check states
instance.isValid();     // Is value valid?
instance.isModified();  // Has value changed?
instance.getError();    // Get current error message

// Re-run validation and reset
instance.validate();    // Validate the current value
instance.reset();       // Restore the original value and config
instance.cleanup();     // Remove handlers and clear field errors

State itself lives in the ElementFactory._privateState WeakMap, not on the instance. Read it through the three methods above.

3. Events

Every element dispatches the native change and input events. In addition, three factories bridge the change into the app event system with EventManager.emit():

Event Emitted by Detail
change Every element Native DOM event
input Every element Native DOM event
element:change DateElementFactory {elementId, value, type: 'date'}
element:change ColorElementFactory {elementId, value, type: 'color'}
element:change RangeElementFactory {elementId, values, type: 'range'}

EventManager.emit() does not dispatch a DOM event, so element:change must be listened to through EventManager.on() - addEventListener('element:change') never fires.

element.addEventListener('change', (e) => {
  const instance = ElementManager.getInstance(e.target);
  console.log('Value:', e.target.value);
  console.log('Valid:', instance.isValid());
});

EventManager.on('element:change', (data) => {
  console.log(data.elementId, data.value, data.type);
});

4. Wrapper Structure

Elements can auto-create wrapper structure:

<!-- Before enhancement -->
<input data-element="text"
       data-wrapper="label"
       data-label="Username"
       data-comment="3-20 characters">

<!-- After enhancement -->
<label class="form-control">
  <span class="label-text">Username</span>
  <input type="text" ...>
  <span class="comment">3-20 characters</span>
</label>

5. Data Binding

<!-- Bind to FormManager data -->
<input data-element="text"
       data-attr="value:user.name"
       name="name">

Element Registration

How ElementManager Works

// Elements register themselves
ElementManager.registerElement('text', TextElementFactory);
ElementManager.registerElement('number', NumberElementFactory);
ElementManager.registerElement('password', PasswordElementFactory);
// ... etc

// Auto-enhancement on page load
document.querySelectorAll('[data-element]').forEach(el => {
  const type = el.dataset.element;
  const factory = ElementManager.getFactory(type);
  if (factory) {
    factory.enhance(el);
  }
});

Registering Custom Elements

// Create custom factory
class PhoneElementFactory extends TextElementFactory {
  static config = {
    ...TextElementFactory.config,
    type: 'tel',
    format: 'xxx-xxx-xxxx'
  };

  static setupElement(instance) {
    // Custom setup
  }
}

// Register with ElementManager
ElementManager.registerElement('phone', PhoneElementFactory);

See Creating Custom Elements for complete guide.

Core Documentation

Element Groups