@form-guardian/dom
v1.0.5
Published
Universal DOM-based form autosave library. Works with any form library (React, Vue, Angular, Svelte) or vanilla HTML forms. Provides attachFormAutosave function with analytics events, batching, and automatic draft restoration.
Maintainers
Readme
@form-guardian/dom
Universal DOM-based form autosave library. Works with any form library (React, Vue, Angular, Svelte) or vanilla HTML forms. Provides attachFormAutosave function with analytics events, batching, and automatic draft restoration.
Overview
@form-guardian/dom is the universal package for form autosave. It works by attaching event listeners to DOM elements, making it compatible with any JavaScript framework or vanilla HTML. It automatically saves form values as users type and can restore them when the form is loaded again.
Installation
npm install @form-guardian/domFeatures
- ✅ Universal Compatibility - Works with React, Vue, Angular, Svelte, or vanilla HTML
- ✅ Automatic Saving - Saves form values as users type (debounced)
- ✅ Automatic Restoration - Optionally restores drafts on form load
- ✅ Analytics Events - Callbacks for
onBeforeSave,onAfterSave,onBeforeRestore,onAfterRestore,onDraftExpired - ✅ Batching - Save changes in batches to reduce storage operations
- ✅ Field Filtering - Blacklist/whitelist specific fields
- ✅ Type Safety - Full TypeScript support with generic types
Quick Start
Vanilla JavaScript
import { attachFormAutosave } from '@form-guardian/dom';
const form = document.querySelector('#my-form');
const autosave = attachFormAutosave({
formId: 'contact-form',
root: form,
autoRestore: true,
debounceMs: 500,
onAfterSave: (values) => {
console.log('Draft saved:', values);
}
});
// Clear draft on successful submit
form.addEventListener('submit', async () => {
await autosave.clear();
});React
import { useEffect, useRef } from 'react';
import { attachFormAutosave } from '@form-guardian/dom';
function MyForm() {
const formRef = useRef<HTMLFormElement>(null);
useEffect(() => {
if (!formRef.current) return;
const autosave = attachFormAutosave({
formId: 'my-form',
root: formRef.current,
autoRestore: true,
onAfterSave: (values) => {
console.log('Saved:', values);
}
});
return () => {
autosave.destroy();
};
}, []);
return <form ref={formRef}>...</form>;
}API
attachFormAutosave<T>(options)
Attach autosave functionality to a form element.
Options
formId(required) - Unique identifier for the formroot(required) - Form or container elementautoRestore(optional) - Automatically restore draft on mount (default:false)debounceMs(optional) - Debounce delay in milliseconds (default:500)ttl(optional) - Time to live for draftsblacklist(optional) - Array of CSS selectors for fields to excludewhitelist(optional) - Array of CSS selectors for fields to explicitly includebatchSaveInterval(optional) - Save changes in batches (milliseconds)onBeforeSave(optional) - Callback before savingonAfterSave(optional) - Callback after savingonBeforeRestore(optional) - Callback before restoringonAfterRestore(optional) - Callback after restoringonDraftExpired(optional) - Callback when draft expires
Returns
A FormAutosaveHandle object with methods:
restore()- Manually restore the draftclear()- Clear the draftdestroy()- Remove event listeners and cleanupgetCurrentValues()- Get current form valueshasDraft()- Check if draft existsgetDraftMeta()- Get draft metadata
Examples
With Analytics
const autosave = attachFormAutosave({
formId: 'checkout-form',
root: form,
onBeforeSave: async (values) => {
// Track save attempt
analytics.track('draft_save_started', { formId: 'checkout-form' });
},
onAfterSave: async (values) => {
// Track successful save
analytics.track('draft_saved', { formId: 'checkout-form', fieldCount: Object.keys(values).length });
},
onDraftExpired: async (draftId) => {
// Track expiration
analytics.track('draft_expired', { draftId });
}
});With Batching
const autosave = attachFormAutosave({
formId: 'large-form',
root: form,
batchSaveInterval: 5000, // Save every 5 seconds
onAfterSave: (values) => {
console.log('Batch saved:', values);
}
});Field Filtering
const autosave = attachFormAutosave({
formId: 'secure-form',
root: form,
// Exclude password fields and sensitive data
blacklist: [
'[data-no-save]',
'input[name="password"]',
'input[name="ssn"]'
],
// But allow specific safe fields
whitelist: [
'input[data-safe]',
'textarea[data-safe]'
]
});TypeScript with Custom Types
interface ContactFormData {
name: string;
email: string;
phone: string;
message: string;
}
const autosave = attachFormAutosave<ContactFormData>({
formId: 'contact-form',
root: form,
onAfterSave: (values) => {
// values is typed as ContactFormData
console.log(values.name); // TypeScript knows this exists
}
});Field Selection
By default, the library tracks:
<input>elements (excepttype="submit",type="button",type="reset",type="password")<textarea>elements- Elements with
contenteditable="true"
Fields are identified by:
nameattribute (preferred)idattributedata-fg-keyattribute
When to Use
Use @form-guardian/dom if you:
- Want universal compatibility with any framework
- Need fine-grained control over autosave behavior
- Are building a custom form solution
- Want to use analytics events and batching
For React applications, consider using @form-guardian/react for a more React-idiomatic API with hooks.
