Form controller for native HTML forms, React, Vue, Svelte, and direct browser usage.
npm install @samline/forms
pnpm add @samline/forms
yarn add @samline/forms
bun add @samline/forms
Use the browser build when you do not have a bundler and need to run the package directly in HTML.
<script src="https://unpkg.com/@samline/[email protected]/dist/browser/global.global.js"></script>
Pin the version in production.
The browser build exposes window.forms.
<form id="contact-form">
<input name="email" type="email" />
</form>
<script src="https://unpkg.com/@samline/[email protected]/dist/browser/global.global.js"></script>
<script>
const contactForm = window.forms.form('contact-form')
contactForm.validate()
</script>
| Entrypoint | Use |
|---|---|
@samline/forms |
Main vanilla API |
@samline/forms/core |
Types, serialization, and validation |
@samline/forms/vanilla |
Explicit DOM API entrypoint |
@samline/forms/react |
React hook |
@samline/forms/vue |
Vue composable |
@samline/forms/svelte |
Svelte store and action |
@samline/forms/browser |
Browser global bundle |
import { form } from '@samline/forms'
const contactForm = form('contact-form', {
validators: {
email: {
required: true,
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
}
}
})
contactForm.onSubmit((element, data, formData, state) => {
console.log(element, data, formData, state)
})
FormDataCreates a controller from:
HTMLFormElementcurrentelement: the bound HTMLFormElement | nullf: alias of elementoptions: normalized controller optionsonSubmit(callback, preventDefault?)autoSubmit(options?)disableAutoSubmit()onSubmit accepts an optional second argument named preventDefault.
onSubmit(callback) is equivalent to onSubmit(callback, true)true, valid submissions are intercepted, which is the right choice for fetch or AJAX flowsfalse, valid submissions continue with the browser's native form submit behaviorfalsewatch(field, callback)observe(field, callback)subscribe(listener)unwatch(field?, callback?)setValue(name, value)getValue(name)getField(name)prefill(fieldName?)validate(fields?)revalidate(fields?)setErrors(fields)clearErrors(fields?)getData()getState()append(options)reset()destroy()Built-in rules supported through validators:
requiredminLengthmaxLengthpatternvalidate for custom callbacksimport { form } from '@samline/forms'
const profileForm = form('profile-form')
const element = document.querySelector('#profile-form') as HTMLFormElement
const profileForm = form(element)
const profileForm = form('profile-form')
profileForm.watch('email', value => {
console.log('email changed:', value)
})
const profileForm = form('profile-form', {
validators: {
email: {
required: true,
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
},
password: {
minLength: 8
}
}
})
const result = profileForm.validate()
console.log(result.isValid, result.errors)
const profileForm = form('profile-form')
profileForm.onSubmit(async (_element, _data, formData) => {
await fetch('/api/profile', {
method: 'POST',
body: formData
})
})
This uses the default preventDefault = true, so the package intercepts the valid submit and lets you handle the request yourself.
const profileForm = form('profile-form')
profileForm.onSubmit(() => {
console.log('validation passed')
}, false)
Use false when the form should continue with its normal HTML submission after validation succeeds, for example in server-rendered applications such as Laravel with Blade.
If validation fails, the package still prevents the submit.
const profileForm = form('profile-form')
profileForm.prefill()
const profileForm = form('profile-form')
const unsubscribe = profileForm.subscribe(state => {
console.log(state.values)
console.log(state.errors)
})
unsubscribe()
MIT