Now.js Framework Documentation
ElementManager
ElementManager
Overview
ElementManager is the custom element management system in Now.js Framework. Used for registering, creating, and enhancing form elements.
When to use:
- Need to create custom form elements
- Need to enhance existing elements
- Need to manage element lifecycle
- Need auto-enhance via attributes
Why use it:
- ✅ Register custom element types
- ✅ Auto-enhance via data-element
- ✅ Instance management
- ✅ Container-based cleanup
- ✅ Weak reference tracking
Basic Usage
Register Element Type
ElementManager.registerElement('currency', {
enhance(element, config) {
// Transform into currency input
element.addEventListener('input', (e) => {
e.target.value = formatCurrency(e.target.value);
});
return element;
},
destroy(instance) {
// Cleanup
}
});HTML Auto-Enhance
<!-- Auto-enhanced by ElementManager -->
<input type="text" data-element="currency" name="price">
<input type="text" data-element="phone" name="phone">
<input type="text" data-element="date" name="birthday">JavaScript API
// Create element programmatically
const element = ElementManager.create('currency', {
name: 'amount',
value: 1000
});
// Enhance existing element
const input = document.querySelector('#price');
ElementManager.enhance(input, { type: 'currency' });API Reference
ElementManager.registerElement(type, implementation)
Register element type
| Parameter | Type | Description |
|---|---|---|
type |
string | Element type name |
implementation |
object | Implementation with enhance/destroy |
ElementManager.registerElement('rating', {
enhance(element, config) {
// Add star rating UI
return element;
},
destroy(instance) {
// Cleanup
}
});ElementManager.create(type, config)
Create new element
| Parameter | Type | Description |
|---|---|---|
type |
string | Registered element type |
config |
object | Configuration |
Returns: HTMLElement
const dateInput = ElementManager.create('date', {
name: 'startDate',
min: '2024-01-01'
});ElementManager.enhance(element, config)
Enhance existing element
| Parameter | Type | Description |
|---|---|---|
element |
HTMLElement | Element to enhance |
config |
object | Configuration |
Returns: Object - Instance
const instance = ElementManager.enhance(input, {
type: 'tags'
});ElementManager.getInstance(id)
Get instance by ID. When two elements on the page share an id, this returns the one
enhanced last; once that one is destroyed, the id finds the other again.
Returns: Object|undefined
ElementManager.getInstanceByElement(element)
Get instance from element. Never returns another element's instance, even when the two
share an id.
Returns: Object|null
ElementManager.scan(container)
Scan and enhance elements in container
| Parameter | Type | Description |
|---|---|---|
container |
HTMLElement | Container (default: document) |
// After loading new content
ElementManager.scan(document.getElementById('form-container'));ElementManager.destroy(id)
Destroy instance
| Parameter | Type | Description |
|---|---|---|
id |
string | Instance ID |
ElementManager.destroyContainer(container)
Destroy all instances in container
// Before removing container
ElementManager.destroyContainer(modal);
modal.remove();ElementManager.hasElement(type)
Check if type is registered
Returns: boolean
Built-in Element Types
Now.js has pre-registered element types:
| Type | Description |
|---|---|
text |
Text input with masking |
number |
Number input with formatting |
date |
Date picker |
select |
Enhanced select |
multiselect |
Multi-select with tags |
color |
Color picker |
tags |
Tag input |
password |
Password with strength |
range |
Range slider |
search |
Search with autocomplete |
Real-World Examples
Custom Element Registration
// Register phone number element
ElementManager.registerElement('phone', {
enhance(element, config) {
element.type = 'tel';
element.placeholder = '(___) ___-____';
element.addEventListener('input', (e) => {
let value = e.target.value.replace(/\D/g, '');
if (value.length > 0) {
value = '(' + value;
}
if (value.length > 4) {
value = value.slice(0, 4) + ') ' + value.slice(4);
}
if (value.length > 10) {
value = value.slice(0, 10) + '-' + value.slice(10, 14);
}
e.target.value = value;
});
return element;
},
destroy(instance) {
// Remove listeners if needed
}
});Form with Auto-Enhanced Elements
<form id="contact-form">
<input data-element="text" name="name" placeholder="Name">
<input data-element="phone" name="phone" placeholder="Phone">
<input data-element="email" name="email" placeholder="Email">
<input data-element="date" name="date" placeholder="Preferred Date">
<button type="submit">Submit</button>
</form>
<script>
// Elements are auto-enhanced on page load
// Or manually scan:
ElementManager.scan(document.getElementById('contact-form'));
</script>Dynamic Form Fields
function addField(type, name) {
const element = ElementManager.create(type, {
name: name,
id: `field-${name}`
});
document.getElementById('dynamic-fields').appendChild(element);
}
// Usage
addField('date', 'startDate');
addField('currency', 'budget');Common Pitfalls
⚠️ 1. Register Before Use
// ❌ Using unregistered type
ElementManager.create('custom-type', {});
// ✅ Register first
ElementManager.registerElement('custom-type', {...});
ElementManager.create('custom-type', {});⚠️ 2. Cleanup Before Removing
// ❌ Removing element directly
container.remove();
// ✅ Destroy first
ElementManager.destroyContainer(container);
container.remove();⚠️ 3. Same Id in a Modal and the Page Under It
An element that shares an id with a live element elsewhere gets its own instance and
leaves the other one alone, and destroyContainer() tears down only what lies inside
the container. Ids are still looked up by the browser, though:
document.getElementById() returns whichever element comes first, so a script that
finds a field by id after the modal opened may reach the wrong one. Give modal fields
their own ids:
<!-- ❌ The page already has #customer_no -->
<input type="text" id="customer_no" name="customer_no">
<!-- ✅ -->
<label for="modal_customer_no">Customer code</label>
<input type="text" id="modal_customer_no" name="customer_no">Related Documentation
- FormManager - Form handling
- ComponentManager - Components