Events & callbacks
Two ways to hook in:
| Need | Use |
|---|---|
| Replace the default success/error UI | callback option |
| Keep the default UI, but add logging, CSRF, or analytics | Window events |
You can use both. callback owns the UI; events still fire.
Callback — you own the UI
When callback is a function, formsub does not run the default handler. You handle success, errors, and field errors. The form is not cleared automatically.
js
formsub.newForm({
formId: 'contact-form',
submitButton: '#submit-button',
ajaxUrl: '/api/contact',
callback: (response) => {
if (response.status === 'success') {
showToast(response.message);
document.getElementById('contact-form').reset();
} else if (response.errors) {
response.errors.forEach((err) => {
console.log(err.name, err.error);
});
} else {
alert(response.message);
}
},
});formsub:AfterSubmit still fires after your callback.
Events — keep the default UI
All events are dispatched on window.
| Event | When | event.detail | Cancelable |
|---|---|---|---|
formsub:BeforeSubmit | After validation, before fetch | FormData | Yes — preventDefault() aborts |
formsub:AfterSubmit | After response handling | Response object | Yes (usually ignore) |
formsub:ResponseSuccess | Default handler sees success | Response object | Yes |
formsub:ResponseError | Default handler sees error | Response object | Yes |
ResponseSuccess and ResponseError fire only with the default handler (no callback).
AfterSubmit fires after success, server errors, and network errors. It does not fire when client validation fails or BeforeSubmit is cancelled.
Add fields before submit
js
window.addEventListener('formsub:BeforeSubmit', (event) => {
event.detail.append('csrf_token', getCsrfToken());
event.detail.append('timestamp', Date.now());
});Cancel a submit
js
window.addEventListener('formsub:BeforeSubmit', (event) => {
if (!confirm('Send this message?')) {
event.preventDefault();
}
});Log every finished submit
js
window.addEventListener('formsub:AfterSubmit', (event) => {
console.log('Done:', event.detail.status, event.detail.message);
});Callback + events together
js
formsub.newForm({
formId: 'contact-form',
submitButton: '#submit-button',
ajaxUrl: '/api/contact',
callback: (response) => myApp.handle(response),
});
window.addEventListener('formsub:AfterSubmit', (event) => {
analytics.track('form_submit', { status: event.detail.status });
});Multiple forms
Events are global. The response object includes form_css_id (the form’s id):
js
window.addEventListener('formsub:AfterSubmit', (event) => {
if (event.detail.form_css_id !== 'contact-form') return;
// ...
});