Skip to content

Construct a registration form with validation

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, validationMessage, and validationIcon. 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

ArcGIS account
You need a free ArcGIS Online and/or ArcGIS Location Platform account to access the services used in this tutorial.

Steps

Create a new pen

  1. Go to CodePen to create a new pen for your form application.

Add HTML

  1. 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 component

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     <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>
  2. 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 and close-disable: Displays the opened component by default, and removes the close button from component respectively.
    • heading and width: Sets the component's heading title and width.
    • outside-close-disabled and escape-disabled: Prevents closure by clicking outside the component or pressing the escape key.
    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
      <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>
    
    Expand
  3. Add accompanying calcite-label and calcite-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, and minlength attributes are added on fields to enable validation.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
        <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>
    
    Expand
  4. 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.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
          <!-- Submit form button-->
          <calcite-button id="submit-button" type="submit" form="sign-up-form" slot="footer" width="full">Sign up</calcite-button>
    
    Expand
  5. Next, add a calcite-alert below the calcite-button created in the previous step but still inside the calcite-dialog. The alert will display a success message when the form is submitted successfully and will automatically close after a short duration.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
          <!-- 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>
    
    Expand

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.

  1. Create references to the form and input elements, which will allow you to access and update their properties in later steps.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
        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");
    
    Expand
  2. 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, validationMessage, and validationIcon properties on calcite-input components based on their validity.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
        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;
          }
        }
    
    Expand
  3. Next, add event listeners to the email, username, password, and confirm password calcite-input elements. Using the blur event, display relevant validation messages by calling the setFieldValidation() function from the previous step when an input loses focus:

    • Show a validationMessage if the field is empty when blurred, letting users know the field is required.
    • Show a different validationMessage if the input value does not match the specified patterns, helping users fix formatting errors.
    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
        // 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, "");
          }
        });
    
    Expand

Submit the form

  1. Validate the form when the submit button is pressed. The event.preventDefault() method is used to stop the browser's default <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 checkValidity() method.

    • 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.
    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
        // Form submission
        form.addEventListener("submit", (event) => {
          event.preventDefault();
    
          if (form.checkValidity()) {
            successAlert.open = true;
            form.reset();
          }
        });
    
    Expand
  2. Reset focus to the first input when the success alert closes by using the calciteAlertClose event and calcite-input's setFocus method.

    Learn more about accessibility and keyboard focus.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
        successAlert.addEventListener("calciteAlertClose", () => {
          emailInput.setFocus();
        });
    
    Expand

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.

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.