Awesome
VanJS Form
Fully typed form state management library (with validation) for the VanJS framework. If you are coming
from React, vanjs-form
feels similar to react-hook-form.
Install
yarn add vanjs-form vanjs-core yup
npm i -S vanjs-form vanjs-core yup
Features
- Dead simple
Form
API to create and manage the form state - Fully typed method parameter and return types
- Supports validation with Yup. Zod and Joi coming soon!
- Built with developer experience (DX) in mind
QuickStart
import van from "vanjs-core";
import { Form, yupValidator } from "vanjs-form";
import * as yup from "yup";
const { div, h1, p, input, label, select, form: formEl, button, br } = van.tags;
function App() {
const form = new Form({
initialValues: {
title: "",
name: "",
age: 0,
gender: ""
},
validator: yupValidator(
yup.object({
title: yup.string().required("Required"),
name: yup.string().required("Required"),
age: yup.number().required("Required").min(18, "At least 18 years"),
gender: yup.string().oneOf(["Male", "Female"], "Valid gender required")
})
),
validationMode: "oninput" // Validation is run on input as well as on submit. Defaults to 'onsubmit'
});
// Watch values when they change in the form fields
const observables = form.watch("name", "title");
// Called when form passes validation
const onsubmit = form.handleSubmit((values) => {
console.log({ submittedValues: values });
});
return div(
h1(() => `VanJS Form for ${observables.val.title} ${observables.val.name}`),
formEl(
{ onsubmit: onsubmit },
label("Title"),
div(
label(input(form.register("title", { type: "radio", value: "Mr." })), "Mr."),
label(input(form.register("title", { type: "radio", value: "Ms." })), "Ms."),
label(input(form.register("title", { type: "radio", value: "Mrs." })), "Mrs.")
),
br(),
label("Name"),
input(form.register("name", { autofocus: true })),
br(),
label("Age"),
input(form.register("age", { type: "number", min: "0", max: "100" })),
br(),
label("Gender"),
select(
form.register("gender", { type: "number", min: "0", max: "100" }),
option({ value: "" }, "Select..."),
option({ value: "Male" }, "Male"),
option({ value: "Female" }, "Female")
),
br(),
button({ type: "submit" }, "Submit")
)
);
}
van.add(document.body, App());
API Reference
Form
- The
Form
class controls the form state and has methods to manipulate this state - If
validator
parameter is provided, the submit handler is called if validation passes - Use
validationMode
to control whether validation should occur on input or only on submit
import { Form } from "vanjs-form";
const form = new Form({
initialValues: Record<string, any>,
validator: (values: Record<string, any>) => Record<string, any> | FormError,
validationMode: "onsubmit" | "oninput" // Defaults to onsubmit
});
After the instance is created, you can access the form functions to work with your form.
YupValidator
- The
yupValidator
function takes a YupObjectSchema
and returns avalidator
function
const form = new Form({
initialValues: {
title: "",
name: "",
age: 0,
gender: ""
},
validator: yupValidator(
yup.object({
title: yup.string().required("Required"),
name: yup.string().required("Required"),
age: yup.number().required("Required").min(18, "At least 18 years"),
gender: yup.string().oneOf(["Male", "Female"], "Valid gender required")
})
)
});
Form methods
import { Form } from "vanjs-form";
const form = new Form({
initialValues: Record<string, any>,
validator: (values: Record<string, any>) => Record<string, any> | FormError,
validationMode: "onsubmit" | "oninput" // Defaults to onsubmit
});
form.register();
form.get();
form.set();
form.error();
form.watch();
form.reset();
form.handleSubmit();
Register
- Registers an input with the form
- Merges
additionalProps
into returned object - Returns an object of parameters (
name
,value
,checked
,oninput
,onfocus
) which should be spread unto the input's properties
form.register(name: string, additionalProps: Partial<HTMLElement>): HTMLElement;
Get
- Gets the typed value of the input with the
name
in the form
form.get(name: string): T[typeof name];
Set
- Sets the value of the input with the
name
in the form
form.set(name: string, value: T[typeof name]): void;
Error
- Gets the error of the input with the
name
in the form
form.error(name: string): string;
Watch
- Returns a reactive object containing the specified field values
- No need to wrap in
van.derive()
🙂
form.watch(...names: string[]): State<{}>
Reset
- Resets a form field or the entire form
form.reset(...name: string[]): void // Reset specific fields
form.reset(): void // Reset entire form
Handle submit
- Register a function to use as a submit handler
- If
validator
is specified on the form, the handler is called if validation passes - Returns a new function to be passed to the form element
form.handleSubmit((values: T) => void): (values: T) => void
Contributors
Changelog
- 1.0.2 (Current)
- Disabled call to
form.validateField
onform.reset
to avoid errors on form reset
- Disabled call to