Form extraction
The FormExtractor utility analyzes a DOM element and reports the form elements found inside it, along with enough metadata (selector, label, value, options, state) to target and fill them programmatically.
Basic usage
Section titled “Basic usage”// Through the forms namespace (recommended)const formData = window.agentlet.forms.extract(element, options);
// Or through the extractor directlyconst extractor = window.agentlet.forms.extractor;const formData = extractor.extractFormStructure(element, options);const formElement = document.getElementById('my-form');const formData = window.agentlet.forms.extract(formElement);Options
Section titled “Options”const options = { includeHidden: false, // Include hidden form fields includeDisabled: false, // Include disabled form fields includeReadOnly: true, // Include read-only form fields (default true) includeBoundingBoxes: false, // Include element positioning};
const formData = window.agentlet.forms.extract(element, options);Extra keys are accepted and forwarded to the internal element extraction, but only the keys above are read by the current implementation.
Output structure
Section titled “Output structure”{ metadata: { tagName: 'div', id: 'registration-form', className: 'form-container', url: 'https://example.com/register', title: 'Registration page', }, forms: [ { type: 'form', element: { /* a FormElementInfo describing the <form> itself */ }, elements: [ /* FormElementInfo, one per field in this form */ ], }, ], elements: [ /* FormElementInfo, fields with no enclosing <form> */ ], extractedAt: '2024-01-15T10:30:00.000Z',}Each field, in forms[].elements or the top-level elements array, is a FormElementInfo:
{ tagName: 'input', type: 'email', id: 'user-email', name: 'email', className: 'form-control required', selector: '#user-email', // Single best selector for this element attributes: { type: 'email', name: 'email', required: 'true' }, value: 'user@example.com', // Shape depends on the field type, see below placeholder: 'Enter your email', required: true, disabled: false, readonly: false, visible: true, interactable: true, label: 'Email address', // Or null if no label was found options: null, // Populated for select/radio/checkbox, see below // boundingBox is only present when includeBoundingBoxes is true: // { x, y, width, height, visible }}value by field type
Section titled “value by field type”- Checkbox or radio:
{ checked: boolean, value: string } - Select:
{ selectedValue: string, selectedOptions: Array<{ value, text }> } - File input:
{ files: string[], accept: string } - Everything else (text, email, textarea, …): a plain
string, ornull
options by field type
Section titled “options by field type”- Select:
{ multiple: boolean, options: Array<{ index, value, text, selected, disabled }> } - Radio or checkbox group:
{ group: Array<{ index, value, checked, label }>, groupSize: number } - Everything else:
null
See Select options for a full walkthrough of the select and group shapes.
Usage examples
Section titled “Usage examples”Extract a specific form
Section titled “Extract a specific form”const formElement = document.getElementById('registration-form');const formData = window.agentlet.forms.extract(formElement, { includeHidden: true, includeBoundingBoxes: true,});
formData.forms[0].elements.forEach((element) => { console.log(`${element.type}: ${element.name} - ${element.label}`);});Find all forms on a page
Section titled “Find all forms on a page”const pageData = window.agentlet.forms.extract(document.body);
pageData.forms.forEach((form, index) => { console.log(`Form ${index + 1}: ${form.elements.length} elements`); const requiredFields = form.elements.filter((el) => el.required); console.log(`Required fields: ${requiredFields.map((f) => f.name).join(', ')}`);});Fill fields from extracted data
Section titled “Fill fields from extracted data”function fillFromExtraction(formData, values) { for (const form of formData.forms) { for (const element of form.elements) { const value = values[element.name]; if (value === undefined || !element.interactable) continue;
const domElement = document.querySelector(element.selector); if (!domElement) continue;
if (element.type === 'checkbox') { domElement.checked = Boolean(value); domElement.dispatchEvent(new Event('change', { bubbles: true })); } else { domElement.value = value; domElement.dispatchEvent(new Event('input', { bubbles: true })); } } }}For a higher-level API that already handles this dispatch logic and reports success and failure per field, use form filling instead of writing your own loop.
Performance considerations
Section titled “Performance considerations”For large pages, limit the scope of extraction rather than scanning the whole document:
const container = document.getElementById('main-content');const formData = window.agentlet.forms.extract(container);
// Or extract a specific form onlyconst targetForm = document.querySelector('form[data-form="registration"]');if (targetForm) { const formData = window.agentlet.forms.extract(targetForm);}Error handling
Section titled “Error handling”try { const formData = window.agentlet.forms.extract(element, options);
if (!formData || (!formData.forms.length && !formData.elements.length)) { console.warn('No form elements found in the specified element'); }} catch (error) { console.error('Form extraction failed:', error);
// Fallback to basic form detection const forms = element.querySelectorAll('form'); const inputs = element.querySelectorAll('input, select, textarea'); console.log(`Fallback found: ${forms.length} forms, ${inputs.length} inputs`);}For the clean, AI-oriented export instead of this full structure, see AI-ready forms.
Source: agentlet-core docs/form-extraction.md and src/types/public-api.d.ts at e3f78fa. The full extraction result documented here matches the current FormExtractionResult/FormElementInfo types; older examples in the source document that referenced selector lists with certainty scores, ARIA accessibility metadata, and free-text context were not carried over because they are not part of the current public API.