Learn how to implement form validation with a sign-up registration form using Calcite Components.
Calcite’s form components include built‑in support for validation through properties like status
, validation
, and validation
. When a component’s status
is set to "invalid"
, a styled message and icon appear automatically. Form validation ensures feedback is consistent across browsers and accessible to more users, including assistive technologies (AT).
Prerequisites
Steps
Create a new pen
- Go to CodePen to create a new pen for your form application.
Add HTML
-
In CodePen > HTML, add the HTML boilerplate and contents of the
<head
tag, most importantly the> <script
tag to load Calcite Components. Once added, Calcite Components can be used like any other HTML element, and only those used in the application will be loaded. The CSS will set the background color for the page and define the size for the> calcite-dialog
componentUse dark colors for code blocks <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" /> <title>Calcite Components: Construct a registration form with validation</title> <link rel="stylesheet" type="text/css" href="https://js.arcgis.com/calcite-components/3.2.1/calcite.css" /> <script type="module" src="https://js.arcgis.com/calcite-components/3.2.1/calcite.esm.js"></script> </head> <style> body { background: var(--calcite-color-background); } calcite-dialog { --calcite-dialog-size-x: 400px; } </style> <body> </body> <script> </script> </html>
-
Add a
<form
to a> calcite-dialog
to present it in a non-modal container. The component uses several attributes:id
: Sets the component's unique identifier.open
andclose-disable
: Displays the opened component by default, and removes the close button from component respectively.heading
andwidth
: Sets the component's heading title and width.outside-close-disabled
andescape-disabled
: Prevents closure by clicking outside the component or pressing the escape key.
Use dark colors for code blocks <body> <calcite-dialog open id="sign-up-dialog" heading="Sign up" width="s" close-disabled outside-close-disabled escape-disabled> <form id="sign-up-form"> </form> </calcite-dialog> </body>
-
Add accompanying
calcite-label
andcalcite-input
components to display form fields for collecting email address, username, and password.Built-in HTML form validation attributes are honored, so the
required
,type
, andminlength
attributes are added on fields to enable validation.Use dark colors for code blocks <calcite-dialog open id="sign-up-dialog" heading="Sign up" width="s" close-disabled outside-close-disabled escape-disabled> <form id="sign-up-form"> <!-- Email --> <calcite-label> Email address <calcite-input id="email" name="email" type="email" placeholder="email@example.com" required validation-message="Please enter a valid email. (e.g., email@example.com)"></calcite-input> </calcite-label> <!-- Username --> <calcite-label> Username <calcite-input id="username" name="username" type="text" placeholder="Your username" minlength="3" maxlength="20" pattern="^[A-Za-z0-9_]{3,20}$" required validation-message="A username is required."></calcite-input> </calcite-label> <!-- Password --> <calcite-label> Password <calcite-input id="password" name="password" type="password" placeholder="Create a password" minlength="8" pattern="^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&_*\-])[A-Za-z\d#?!@$%^&_*\-]{8,}$" required validation-message="A password is required."></calcite-input> </calcite-label> <!-- Confirm Password --> <calcite-label> Confirm password <calcite-input id="confirm-password" name="confirmPassword" type="password" placeholder="Re-enter password" required validation-message="Both passwords must match."></calcite-input> </calcite-label> </form> </calcite-dialog>
-
Add a
calcite-button
outside of the<form
element but within the> calcite-dialog
component. This button is used to submit the form and will reset the form and its validation states after a successful submission.Use dark colors for code blocks <!-- Submit form button--> <calcite-button id="submit-button" type="submit" form="sign-up-form" slot="footer" width="full">Sign up</calcite-button>
-
Next, add a
calcite-alert
below thecalcite-button
created in the previous step but still inside thecalcite-dialog
. The alert will display a success message when the form is submitted successfully and will automatically close after a short duration.Use dark colors for code blocks <!-- Success alert --> <calcite-alert id="success-alert" icon="check-circle" kind="success" scale="s" auto-close auto-close-duration="fast"> <div slot="title">You've successfully signed up!</div> </calcite-alert>
Add validation
In the <script
tag, add JavaScript to implement validation and reset logic to the form's fields. The email address input you created earlier will use built-in <form
validation by setting its type
to "email"
and adding the required
attribute. This allows the browser to automatically check for a valid email format while using JavaScript to present a required message on blur
. The username and password fields will have additional validation added to make sure the entered values meet specified requirements.
-
Create references to the form and input elements, which will allow you to access and update their properties in later steps.
Use dark colors for code blocks const form = document.getElementById("sign-up-form"); const emailInput = document.getElementById("email"); const usernameInput = document.getElementById("username"); const passwordInput = document.getElementById("password"); const confirmPasswordInput = document.getElementById("confirm-password"); const submitButton = document.getElementById("submit-button"); const successAlert = document.getElementById("success-alert");
-
Create a helper function that updates the validation state of the input fields. This function will help you show clear feedback to users by setting the
status
,validation
, andMessage validation
properties onIcon calcite-input
components based on their validity.Use dark colors for code blocks function setFieldValidation( field, message, icon = "exclamation-mark-triangle" ) { if (message) { field.status = "invalid"; field.validationMessage = message; field.validationIcon = icon; } else { field.status = "idle"; field.validationMessage = ""; field.validationIcon = null; } }
-
Next, add event listeners to the email, username, password, and confirm password
calcite-input
elements. Using theblur
event, display relevant validation messages by calling theset
function from the previous step when an input loses focus:Field Validation() - Show a
validation
if the field is empty when blurred, letting users know the field is required.Message - Show a different
validation
if the input value does not match the specified patterns, helping users fix formatting errors.Message
Use dark colors for code blocks // Email required validation check on blur emailInput.addEventListener("blur", () => { const value = emailInput.value; if (!value) { setFieldValidation(emailInput, "An email is required."); } else { setFieldValidation(emailInput, ""); } }); // Username required and pattern match validation checks on blur usernameInput.addEventListener("blur", () => { const value = usernameInput.value; const pattern = /^[A-Za-z0-9_]{3,20}$/; if (!value) { setFieldValidation(usernameInput, "A username is required."); } else if (!pattern.test(value)) { setFieldValidation( usernameInput, "Username must be 3 to 20 characters, using a combination of letters, numbers, or underscores." ); } else { setFieldValidation(usernameInput, ""); } }); // Password required and pattern match validation checks on blur passwordInput.addEventListener("blur", () => { const value = passwordInput.value; const pattern = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&_*\-]).{8,}$/; if (!value) { setFieldValidation(passwordInput, "A password is required."); } else if (!pattern.test(value)) { setFieldValidation( passwordInput, "The password must be 8 or more characters and include uppercase, lowercase, number, and special characters." ); } else { setFieldValidation(passwordInput, ""); } }); // Confirm password match validation on blur confirmPasswordInput.addEventListener("blur", () => { const value = confirmPasswordInput.value; if (!value) { setFieldValidation( confirmPasswordInput, "A password confirmation is required." ); } else if (value !== passwordInput.value) { setFieldValidation(confirmPasswordInput, "The passwords do not match."); } else { setFieldValidation(confirmPasswordInput, ""); } });
- Show a
Submit the form
-
Validate the form when the submit button is pressed. The
event.prevent
method is used to stop the browser's defaultDefault() <form
submission behavior. This allows you to handle validation and display custom messages without reloading the page or navigating the user away from the interface. The function will then check for overall validity of the> <form
with the native> check
method.Validity() - When all fields are valid: A
calcite-alert
is opened so the user knows the submission was successful and the entered values are reset using the<form
's> reset()
method. - When any of the form's fields are invalid: The form remains visible and validation messages are displayed next to the fields that need correction.
Use dark colors for code blocks // Form submission form.addEventListener("submit", (event) => { event.preventDefault(); if (form.checkValidity()) { successAlert.open = true; form.reset(); } });
- When all fields are valid: A
-
Reset focus to the first input when the success alert closes by using the
calcite
event andAlert Close calcite-input
'sset
method.Focus Learn more about accessibility and keyboard focus.
Use dark colors for code blocks successAlert.addEventListener("calciteAlertClose", () => { emailInput.setFocus(); });
Run the app
In CodePen, run your code to display the registration form.
Your application now includes a sign-up form with fields for email, username, password, and confirm password. Try submitting the form without filling it out to display the validation messages. As you interact with the form, required fields will display validation feedback when left empty and fields with custom validation will display parameters for passing validation.