Now.js Framework Documentation
Form Elements - Overview
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
- Overview
- Architecture
- Quick Start
- Element Types
- Quick Selection Guide
- Common Features
- Element Registration
- 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 APIArchitecture
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
└── TagsElementFactoryCore 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 |
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 errorsState 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.
Related Documentation
Core Documentation
- ElementFactory - Base class reference
- FormManager - Form-level management
- FormError - Error handling
Element Groups
- Text Elements - Text, Password, Search
- Number Elements - Number, Currency
- Select Elements - Select, MultiSelect
- Date Elements - Date picker
- Special Elements - Color, Range, Tags, Mask, Textarea
- Creating Custom Elements - Build your own
Related Components
- FileElementFactory - File upload
- EditInPlaceManager - Inline editing