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
<headtag, most importantly the> <scripttag 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-dialogcomponentUse dark colors for code blocks <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=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.3.3/calcite.css" /> <script type="module" src="https://js.arcgis.com/calcite-components/3.3.3/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
<formto a> calcite-dialogto present it in a non-modal container. The component uses several attributes:id: Sets the component's unique identifier.openandclose-disable: Displays the opened component by default, and removes the close button from component respectively.headingandwidth: Sets the component's heading title and width.outside-close-disabledandescape-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-labelandcalcite-inputcomponents to display form fields for collecting email address, username, and password.Built-in HTML form validation attributes are honored, so the
required,type, andminlengthattributes 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-buttonoutside of the<formelement but within the> calcite-dialogcomponent. 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-alertbelow thecalcite-buttoncreated 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 validationproperties onIcon calcite-inputcomponents 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-inputelements. Using theblurevent, display relevant validation messages by calling thesetfunction from the previous step when an input loses focus:Field Validation() - Show a
validationif the field is empty when blurred, letting users know the field is required.Message - Show a different
validationif 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.preventmethod is used to stop the browser's defaultDefault() <formsubmission 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> <formwith the native> checkmethod.Validity() - When all fields are valid: A
calcite-alertis 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
calciteevent andAlert Close calcite-input'ssetmethod.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.