Forms & markup
formsub works with a plain HTML form. You style it; formsub only reads values and writes error text.
Form element
html
<form id="contact-form">
<!-- fields -->
</form>The id must match formId. Native action and method are ignored — submission goes through fetch to ajaxUrl.
Field naming
Every submitted field needs a name:
html
<input name="email" type="email" required />
<select name="topic">...</select>
<textarea name="message"></textarea>Wrap the control in a <label> so the error <span> lands next to the field:
html
<label class="field">
Email
<input name="email" type="email" required autocomplete="email" />
</label>Supported controls
| Control | What is sent |
|---|---|
| text, email, tel, hidden, number, … | Current value |
select, textarea | Current value |
checkbox, radio | Sent only when checked |
file | Selected files; empty file inputs are skipped |
submit, button, reset, image | Skipped |
File uploads
html
<form id="upload-form" enctype="multipart/form-data">
<input name="attachment" type="file" accept=".pdf,.png" />
</form>enctype is optional for FormData + fetch, but it documents intent. Always validate type and size on the server — accept is only a hint.
Checkboxes
html
<label>
<input type="checkbox" name="terms" value="1" required />
I agree to the terms
</label>Unchecked boxes are omitted from FormData.
Field errors
On validation failure (client or server), formsub inserts:
html
<span class="error-message">This field is required</span>inside the field's parent and may add class error:
html
<label class="error">
Email
<input name="email" type="email" />
<span class="error-message">Invalid email address</span>
</label>Error text is set with textContent, not innerHTML. Style the classes in your CSS:
css
.error-message {
color: #b00020;
font-size: 0.875rem;
}
label.error input,
label.error select,
label.error textarea {
outline: 1px solid #b00020;
}Loading indicator
html
<button type="submit" id="submit-button">Send</button>
<p id="loading" class="hidden">Sending…</p>js
indicator: '#loading'See Configuration for the class toggling rules.
Math captcha
html
<input name="numb_captcha" type="text" required autocomplete="off" />formsub sets a placeholder like 3 + 7 = ? and injects hidden num1 / num2 fields. Details are on Validation.
Multiple forms
Call newForm once per form, each with its own formId:
js
formsub.newForm({
formId: 'newsletter-form',
submitButton: '#newsletter-submit',
ajaxUrl: '/api/newsletter',
});
formsub.newForm({
formId: 'contact-form',
submitButton: '#contact-submit',
ajaxUrl: '/api/contact',
});Window events are shared. Filter by event.detail.form_css_id if you listen globally — see Events & callbacks.