Forms

Updated:

Use forms to allow people to enter data for use by the application, or to configure options

Layout and Interaction

  • Use a single-column layout.

A single-column form makes the completion path easier to understand compared to a multi-column layout. While there are a few rare exceptions to this guidance (e.g. city/state/ZIP code or first name/last name),single-column form layouts consistently outperform multi-column layouts in usability testing and eye-tracking studies.

  • Distinguish optional fields from required ones.

Set the optional attribute on form fields to append "(optional)" to the field label. This will also set aria-required to false.

  • Explain any field-specific requirements.

Use the hints array to show field requirements when the user is focused on the field. Don't make users guess the expected format.

  • Provide clear and specific error feedback.

Review the "Validation" section below for guidance on handling form errors.

  • Avoid placeholder text

Form field placeholder text presents a number of potential usability and accessibility difficulties:

  • Increased likelihood that users will miss form fields since placeholder text can look like actual form input
  • Default styles for placeholder text typically fail to meet the 4.5:1 contrast ratio recommended by WCAG
  • Placeholder text disappears on focus or input, requiring the user to remember the placeholder content and increasing cognitive load
  • Not all screen readers will announce placeholder text, making the placeholder text content inaccessible to some users

To provide form field help to the user and avoid the issues with placeholder text, present the content using the field's hints array instead.

  • Be careful with disabled form elements

Disabled form fields and controls are typically used to prevent the user from submitting invalid data or from performing disallowed actions; however, consider the potential drawbacks of disabled form elements:

  • Disabled elements give no feedback to the user about why they are disabled, forcing the user to review the page themselves to assess how to solve the issue. Consider using form validation and inline feedback to help the user correct mistakes instead of disabling controls.
  • Styles for disabled elements often have low contrast. While WCAG 2.0 does not require minimum contrast for disabled controls (Link), there is still a risk that users will miss important information if they are unable to read the disabled element.
  • Disabled form elements are removed from the normal tab/focus order of the document. Screen reader users must use special screen reader navigation controls to access the disabled element, making the element easier to miss when reviewing the page.
Reward Checking *1234 Member Savings *9876 HELOC *7703 Reward Checking *1234 Member Savings *9876 HELOC *7703
Secondary action Primary action
<div class="form-container">
  <q2-select label="From account">
    <q2-option
      value="1"
      display="Reward Checking *1234"
    >
      Reward Checking *1234
    </q2-option>
    <q2-option
      value="2"
      display="Member Savings *9876"
    >
      Member Savings *9876
    </q2-option>
    <q2-option
      value="3"
      display="HELOC *7703"
    >
      HELOC *7703
    </q2-option>
  </q2-select>

  <q2-select label="To account">
    <q2-option
      value="1"
      display="Reward Checking *1234"
    >
      Reward Checking *1234
    </q2-option>
    <q2-option
      value="2"
      display="Member Savings *9876"
    >
      Member Savings *9876
    </q2-option>
    <q2-option
      value="3"
      display="HELOC *7703"
    >
      HELOC *7703
    </q2-option>
  </q2-select>

  <q2-calendar label="Transfer date"></q2-calendar>

  <q2-input label="Transfer amount" type="currency"></q2-input>

  <q2-input label="Transfer memo" optional></q2-input>

  <div class="btn-container wide">
    <q2-btn block color="secondary">Secondary action</q2-btn>
    <q2-btn block color="primary">Primary action</q2-btn>
  </div>
</div>

Validation

Tecton components do not come with built-in validation. It is up to the developer to handle validation logic and update the errors property accordingly on corresponding components to display any issues to the user.

We recommend doing this by adding event listeners to either the input or change events. Below is an example of a simple implementation of how this could be done in a server-rendered extension:

const input = document.querySelector("q2-input[type=email]")
input.addEventListener("input", (event) => {
  const isMysteriousDomain = event.detail.value.endsWith("@mysterious-domain.com")
  if (isMysteriousDomain) {
    input.errors = ['We do not allow email addresses from mysterious-domain.com'];
  } else {
    input.errors = [];
  }
})

References and Further Reading