Modules
StringForm
Validates form inputs declaratively and emits structured form lifecycle events.
StringForm
StringForm turns a native <form> into a declarative validation surface. Rules live directly in string-input, helper blocks mirror field state, and successful submit data is emitted through scoped events.
Public API
Attributes
| Attribute | Target | Default | Real runtime effect |
|---|---|---|---|
string="form" | <form> | required | Activates the module on that form. |
string-id | <form> | auto-generated | Names scoped submit and invalid events. |
| `string-input="rule | list"` | <input>, <select>, <textarea> | "" |
string-id | field elements | none | Overrides the field key used by group, error, and field events. |
string-input="group[key]" | helper container | none | Mirrors -valid, -invalid, and -error from the field with that key. |
string-input="error[key]" | helper container | none | Receives one <span> per current error message for that field. |
Rules are parsed with |, and parameterized rules support both rule:param and rule(param).
Examples:
required|min:2emailsame:passwordpattern(^[a-z0-9-]+$)
CSS Variables and DOM Output
StringForm does not write CSS variables. Its public output is:
- classes on fields:
-inited,-valid,-invalid,-error - mirrored classes on
group[key]helpers:-valid,-invalid,-error - rendered error
<span>nodes insideerror[key]helpers - scoped form and field events
The live phase uses -invalid. The submit phase uses -error.
Events
| Channel | Payload | Fired when |
|---|---|---|
form:submit:<id> | Record<string, any> | The form passes validation on submit |
form:invalid:<id> | void | Submit is attempted with at least one invalid field |
form:field:valid:<key> | { key, field, errors, phase, valid } | A field becomes valid |
form:field:invalid:<key> | { key, field, errors, phase, valid } | A field fails live validation |
form:field:error:<key> | { key, field, errors, phase, valid } | A field fails submit validation |
TypeScript
stringTune.on('form:submit:contact', (data) => {
console.log(data);
});
stringTune.on('form:field:error:email', ({ errors }) => {
console.log(errors);
});
Mirror Behavior
This module has no mirror output contract.
Quick Example
HTML
<form string="form" string-id="contact" class="form-demo">
<div class="grid">
<div class="field" string-input="group[name]">
<label for="name">Name</label>
<input id="name" name="name" string-input="required|min:2" />
<div class="errors" string-input="error[name]"></div>
</div>
<div class="field" string-input="group[email]">
<label for="email">Email</label>
<input id="email" name="email" type="email" string-input="required|email" />
<div class="errors" string-input="error[email]"></div>
</div>
<div class="field full" string-input="group[contact-pref]">
<label>Preferred contact</label>
<label class="choice">
<input type="radio" name="contact-pref" value="email" string-input="required" />
<span>Email</span>
</label>
<label class="choice">
<input type="radio" name="contact-pref" value="phone" string-input="required" />
<span>Phone</span>
</label>
<div class="errors" string-input="error[contact-pref]"></div>
</div>
</div>
<button type="submit">Send</button>
</form>
CSS
.form-demo {
display: grid;
gap: 20px;
border: 1px solid black;
padding: 24px;
}
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 20px;
}
.field {
display: grid;
gap: 8px;
padding: 12px;
border: 1px solid black;
}
.field input,
.field select,
.field textarea,
.form-demo button {
min-height: 48px;
border: 1px solid black;
background: white;
color: black;
padding: 0 12px;
}
.field.-error input,
.field.-error select,
.field.-error textarea {
border-color: #c00;
color: #c00;
}
.choice {
display: flex;
gap: 10px;
align-items: center;
}
.full {
grid-column: 1 / -1;
}
.errors {
min-height: 18px;
font-size: 12px;
color: #c00;
}
Registration
TypeScript
import StringTune, { StringForm } from '@fiddle-digital/string-tune';
const stringTune = StringTune.getInstance();
stringTune.use(StringForm);
stringTune.start(60);
Detailed Behavior
- Field keys resolve in this order:
string-id,name,id, generated fallback. - Checkbox groups with the same
namereturn an array when multiple values are checked. - Radio groups emit the selected value, or an empty string when nothing is selected.
- File inputs emit
FileorFile[]values when files are present. - The module blocks illegal keystrokes during
beforeinputfor rules such asnumber,integer,email,phone,digits,url, andpattern. - On failed submit, the first invalid field is focused automatically.