Standalone Fields
Not every validated input lives inside a <form>. The initField() function lets you enhance individual fields independently — useful for search bars, inline edits, or widget inputs.
Basic Usage
Section titled “Basic Usage”<div data-form-field="search" data-validate='[{"type":"StringLength","options":{"minimum":2,"message":"Enter at least 2 characters"}}]'> <label for="search">Search</label> <input id="search" type="text" /> <div id="search-errors" class="invalid-feedback"></div></div>import { initField, registerDefaultValidators } from 'formlayer';
registerDefaultValidators();
const ctrl = initField(document.getElementById('search')!);
ctrl.on('valid', (state) => { performSearch(state.value);});With a Custom Field Type
Section titled “With a Custom Field Type”Pass an explicit field class — standalone fields do not use the global field-type registry or data-field-type auto-discovery:
import { ComboboxField } from 'formlayer-plugin-combobox';
const comboCtrl = initField(mySelectWrapper, { field: ComboboxField });For lazy-loaded custom fields:
const comboCtrl = await initFieldAsync( mySelectWrapper, () => import('formlayer-plugin-combobox'),);initField and initFieldAsync construct the field and run its DOM setup (mount()) in one step, so the returned controller is ready to use immediately. Custom fields built on AbstractDomFormField are initialized this way — do not call new MyField(wrapper) yourself, as a bare instance is constructed but not mounted.
With Custom Options
Section titled “With Custom Options”Pass an InitFieldOptions object as the second argument:
const ctrl = initField(myElement, { validate(value, rules, defaultValidate) { const result = defaultValidate(); if (result.isValid && value.includes('admin')) { return { isValid: false, errors: ['Reserved word'] }; } return result; },
onServerErrors(errors, fieldName) { return errors.map(e => `Server: ${e}`); },
errorsSelector: '[data-field-error]', renderError: ({ message }) => `<span class="field-error">${message}</span>`, errorsSeparator: '',});For icons, custom container placement, form-level summaries, and the full option reference, see Error Rendering.
Programmatic Control
Section titled “Programmatic Control”initField() returns a FieldController with full control:
const ctrl = initField(myInput);
// Read stateconsole.log(ctrl.state);// { name: "search", value: "", isValid: true, isDirty: false, isTouched: false, errors: [] }
// Set value programmaticallyctrl.setValue('hello');
// Trigger validationconst result = ctrl.validate();console.log(result.isValid, result.errors);
// Listen for changesctrl.on('change', (state) => { console.log('New value:', state.value);});
// Reset to initial statectrl.reset();
// Clean upctrl.destroy();Accepting a Bare Input
Section titled “Accepting a Bare Input”You can pass an <input> directly — initField resolves the closest [data-form-field] wrapper:
const input = document.querySelector('#search input') as HTMLInputElement;const ctrl = initField(input);If the input is not inside a [data-form-field] wrapper, initField throws an error.