COOKBOOK / LIVE EXAMPLE
Form Validation example with VSN.js
Real markup. Real VSN. Try it below.
← All examples · Open full screen ↗
View example source
<section id="validation-example" class="example-card cookbook-example">
<header class="cookbook-heading">
<div>
<p class="cookbook-eyebrow">cookbook</p>
<h1>Form validation</h1>
<p class="cookbook-lede">
Inputs use two-way binding while validation state drives error text and ARIA attributes.
</p>
</div>
<span class="cookbook-badge">bind + validate</span>
</header>
<form class="cookbook-form cookbook-form-narrow" novalidate vsn-on:submit!prevent="submit();">
<label class="cookbook-field">
<span>Name</span>
<input
id="validation-name"
name="name"
type="text"
autocomplete="name"
aria-describedby="name-error"
vsn-bind="name"
vsn-on:input="clearName();"
/>
<small id="name-error" class="field-error" vsn-show="nameError" vsn-bind:from="nameError"></small>
</label>
<label class="cookbook-field">
<span>Email</span>
<input
id="validation-email"
name="email"
type="email"
autocomplete="email"
aria-describedby="email-error"
vsn-bind="email"
vsn-on:input="clearEmail();"
/>
<small id="email-error" class="field-error" vsn-show="emailError" vsn-bind:from="emailError"></small>
</label>
<label class="cookbook-field">
<span>Note <em>(optional)</em></span>
<textarea name="note" rows="3" vsn-bind="note"></textarea>
</label>
<div class="cookbook-actions">
<button class="btn" type="submit">Validate form</button>
<span class="cookbook-inline-status" vsn-show="submitted" vsn-bind:from="formMessage"></span>
</div>
</form>
<p class="cookbook-note">
This example does not submit to a server; it shows how a server response can map back to field state.
</p>
</section>
<script type="text/vsn">
#validation-example {
name: "";
email: "";
note: "";
nameError: "";
emailError: "";
formMessage: "";
submitted: false;
valid: false;
clearName() {
nameError = "";
submitted = false;
}
clearEmail() {
emailError = "";
submitted = false;
}
validate() {
valid = true;
nameError = "";
emailError = "";
if (name.trim() == "") {
nameError = "Name is required.";
valid = false;
}
if (email.trim() == "" || !email.includes("@")) {
emailError = "Enter a valid email address.";
valid = false;
}
}
submit() {
submitted = false;
validate();
if (valid) {
formMessage = "Looks good. The form is ready to submit.";
submitted = true;
}
}
#validation-name {
@aria-invalid :< (nameError != "" ? "true" : "false");
@class :< { "is-invalid": nameError != "" };
}
#validation-email {
@aria-invalid :< (emailError != "" ? "true" : "false");
@class :< { "is-invalid": emailError != "" };
}
}
</script>