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);}); Live Preview
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'),);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.