StringTune/Docs

Modules

StringForm

Validates form inputs declaratively and emits structured form lifecycle events.

Type
Built-in module
Status
Stable
Scope
Element-level
Activation
string="form"

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

AttributeTargetDefaultReal runtime effect
string="form"<form>requiredActivates the module on that form.
string-id<form>auto-generatedNames scoped submit and invalid events.
`string-input="rulelist"`<input>, <select>, <textarea>""
string-idfield elementsnoneOverrides the field key used by group, error, and field events.
string-input="group[key]"helper containernoneMirrors -valid, -invalid, and -error from the field with that key.
string-input="error[key]"helper containernoneReceives 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:2
  • email
  • same:password
  • pattern(^[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 inside error[key] helpers
  • scoped form and field events

The live phase uses -invalid. The submit phase uses -error.

Events

ChannelPayloadFired when
form:submit:<id>Record<string, any>The form passes validation on submit
form:invalid:<id>voidSubmit 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 name return an array when multiple values are checked.
  • Radio groups emit the selected value, or an empty string when nothing is selected.
  • File inputs emit File or File[] values when files are present.
  • The module blocks illegal keystrokes during beforeinput for rules such as number, integer, email, phone, digits, url, and pattern.
  • On failed submit, the first invalid field is focused automatically.