# Form Field

Forms are some of the most complex user interactions in modern application development. The Kickstand UI form field component is designed to abstract away some of that complexity and provide a consistent user experience as well as some features to improve usability.

One of the primary goals of Kickstand UI is to take advantage of native browser functionality as often as possible, so the <ks-form-field> component leverages HTML5 input elements and validation to reduce code size increase functionality.

# Text (Default)

<ks-form-field label="Username" />

# Checkbox

<ks-form-field type="checkbox" label="I declare bankruptcy" />

# Checklist

Checklists are great if users need to be able to choose multiple options from a predetermined list. Kickstand UI's checklist leverages the existing <option> element to provide the checklist options and just like the option element you can pre-select options using the select attribute as well as specify alternate values with the value attribute.

<ks-form-field type="checklist" label="Choose your next office mates">
    <option selected>michael.scott@dundermifflin.com</option>
    <option>dwight.schrutte@dundermifflin.com</option>
    <option selected>pam.beasley@dundermifflin.com</option>
    <option>jim.halpert@dundermifflin.com</option>
    <option>Meredith.palmer@dundermifflin.com</option>
</ks-form-field>

# Value

You can also specify a value if you would like the selected values to be different from the display text.

<ks-form-field type="checklist" label="Choose your next office mates">
    <option value="michael.scott@dundermifflin.com" selected>Michael Scott</option>
    <option value="dwight.schrutte@dundermifflin.com">Dwight Schrutte</option>
    <option value="pam.beasley@dundermifflin.com" selected>Pam Beasley</option>
    <option value="jim.halpert@dundermifflin.com">Jim Halpert</option>
    <option value="Meredith.palmer@dundermifflin.com">Meredith Palmer</option>
</ks-form-field>

The value returned from a checklist form field is an array of the values that have been selected.

# Color

The color input utilizes the HTML5 color-picker for users to select colors colors from a color wheel or manually enter it in various formats. The value returned is in hexadecimal format.

<ks-form-field type="color" label="Your favorite color" />

Note

The HTML5 color input type is not supported by all browsers (opens new window). If it is not supported, the input will fall back to a text box where the user can enter a color value.

# Datalist

Similar to the select input, the type to datalist will provide you a list of suggestions that are filterable. In order to display the datalist options, make sure the datalist property is true

<ks-form-field
    label="Email"
    type="datalist"
    datalist
    >
    <option>michael.scott@dundermifflin.com</option>
    <option>dwight.schrutte@dundermifflin.com</option>
    <option>pam.beasley@dundermifflin.com</option>
    <option>jim.halpert@dundermifflin.com</option>
    <option>Meredith.palmer@dundermifflin.com</option>
</ks-form-field>

WARNING

The HTML5 datalist feature is supported by all modern browsers (opens new window), but is not consistently implemented. Make sure you test in different browsers to ensure you get the user experience you are looking for.

# Date

<ks-form-field type="date" label="Choose your birthday" />

# Month

<ks-form-field type="month" label="Credit Card Expiration" />

# Week

<ks-form-field type="week" label="Week of your reservation" />

# Time

<ks-form-field type="time" label="What time is it?" />

WARNING

The "date" input types (date, month, week, time, etc.) do not have great browser coverage (opens new window). Please make sure to test to ensure you have the desired user experience. There are also polyfills available, to provide consistency across browsers.

# Email

<ks-form-field type="email" label="Email" />

# Custom Validation

The email type can work nicely with the pattern attribute to create custom validation. The following example allows only emails with a specific domain.

<ks-form-field type="email"  label="Email" pattern=".+@dundermifflin.com" />

# Number

<ks-form-field type="number" label="Age" />

# Min/Max Value

You can control the minimum and maximum values using the min and max attributes.

<ks-form-field
    type="number"
    min="5"
    max="10"
    label="Pick a number between 5 and 10"
    />

# Password

<ks-form-field type="password" label="Password" />

# Radiolist

Checklists are great if users need to be able to choose multiple options from a predetermined list. Kickstand UI's checklist leverages the existing <option> element to provide the checklist options and just like the option element you can pre-select options using the select attribute as well as specify alternate values with the value attribute.

<ks-form-field type="radiolist" label="Choose your next office mate">
    <option value="michael.scott@dundermifflin.com">Michael Scott</option>
    <option value="dwight.schrutte@dundermifflin.com">Dwight Schrutte</option>
    <option value="pam.beasley@dundermifflin.com" selected>Pam Beasley</option>
    <option value="jim.halpert@dundermifflin.com">Jim Halpert</option>
    <option value="Meredith.palmer@dundermifflin.com">Meredith Palmer</option>
</ks-form-field>

# Range

<ks-form-field type="range" label="Volume" />

# Tel

<ks-form-field
    type="tel"
    pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
    label="Telephone Number"
    help-text="XXX-XXX-XXXX"
    />

It is important to note that the tel input type does not provide any default validation (because phone numbers patterns can vary), so it is important to use it in conjunction with the pattern attribute. Using the tel input.

Note

Before you decide to ditch the tel input type for the standard text field, there are still some benefits to using tel:

  • It can provide a custom keyboard for mobile and touch enabled devices
  • Browser and third-party autocomplete tools can use it to speed up your user's form entry

# Textarea

A textarea is for adding multi-line plain-text editing. This is very useful when you want to allow users to enter a large amount of free-form text, for example a comment on a review or feedback form.

<ks-form-field
    label="Comments"
    type="textarea"
    />

# Select

Setting the type property to select allows you nest a list of options within the form field component to provide the user available options.

<ks-form-field
    label="Options"
    type="select"
    >
    <option value="1" selected>Option 1</option>
    <option value="2">Option 2</option>
    <option value="3">Option 3</option>
</ks-form-field>

# Label

The label property is pretty straight forward in that it provides the label for your form field. Every form field must have a label and placeholder text is not a suitable replacement for a label.

# Help Text

The help-text is additional information provided for the user to increase input accuracy. Developers have commonly used placeholder text for this information in the past, but this results in some usability issues such as the loss of that information when a value is input into the field. Also, to improve usability, the help text is displayed above the form field and is actually part of the <label>.

Note

Clicking a label automatically sets the focus on associated input field, so having your help text as part of your label provides a larger target to interact with the form field - especially for touch-enabled devices. Having the text above the form field also means that it won't be covered up on mobile devices when the keyboard is displayed.

<ks-form-field
    label="Password"
    type="password"
    help-text="Must contain at least 8 characters"
    minlength="8"
    />

# Tooltip Text

If you need to provide the user with additional information that may not need to be displayed every time a user interacts with the form, you can display it in a tooltip.

<ks-form-field
    label="Email"
    type="email"
    tooltip-text="Used for password recovery"
    />

# Error Messages

In order to provide clear error messages to you users, invalid input fields will be bordered in red and the error message will also be display in red to help it stand out from the label and help text. For those users that may not be able to distinguish between the colors, an "alert" icon has been added to call attention to the invalid field and message.

Note

The error message is also included in the <label> to provide better usability.

# Validation

With implementation of HTML 5, there are a number of great validation tools that come out-of-the-box for form fields. Kickstand UI takes advantage of those capabilities and provides some additional features for custom validation.

# Validation Properties

Each fo the validation properties has a corresponding error message you can easily customize.

Validation Error Message Usage
value bad-input-error-message This error will display if the user has provided input that the browser is unable to convert.
invalid default-error-message Provides the ability to manually toggle the input's validity.
max max-error-message Specifies the maximum value of numerical input types
maxlength maxlength-error-message Specifies the maximum length of textual data (strings)
min min-error-message Specifies the minimum value of numerical input types
minlength minlength-error-message Specifies the minimum length of textual data (strings)
pattern pattern-error-message Specifies a regular expression that defines a pattern the entered data needs to follow.
required required-error-message Specifies whether a form field needs to be filled in before the form can be submitted.
step step-error-message Specifies what increment the value will go up or down by when the input controls are used (such as the up and down number buttons).
type type-error-message Specifies whether the data needs to be a number, an email address, or some other specific preset type.

TIP

To find out more about HTML5 form validation check out this documentation from MDN (opens new window).

# Validate On Input

By default the form field will be validated once the user leaves the form field (onBlur). If you need to override this behavior to when the user presses the key (onInput), you can add the validate-on-input property to override the default behavior.

# validate()

You can also manually trigger field validation by selecting the field and executing the validate() method.

<ks-form-field id="username" label="Username" required />
<script>
    (function(){
        let username = document.getElementById('username');
        username.validate();

        // you can also get the field data
        username.validate().then(fieldData => {
            // do something awesome
        });
    })();
</script>

# Data Binding

Kickstand UI's components use one-way data binding so that data flows in a single direction. What that means is that the variable you bind to the value property will not be updated whenever a user enters new content. In order to provide you with the new value, each component will emit and updated event.

# Adding Event Listeners

Bound Value:
<ks-form-field label="Name" id="binding_test" class="mb-md" />
<b>Bound Value: </b><span id="bound_value"></span>
<script>
    (function(){
        let formField = document.getElementById('binding_test');
        let value = document.getElementById('bound_value');
        formField.addEventListener('updated', function (e) {
            value.innerText = e.detail.value;
        });
    })();
</script>

TIP

Many JavaScript frameworks come with built-in event handling to help simplify your code.

# Vue.js

<ks-form-field label="Name" id="binding_test" @updated="(e) => myMethod(e)" />

# React

<ks-form-field label="Name" id="binding_test" onUpdated="(e) => onUpdatedHandler(e)" />

# Event Detail

Event details emit much more that just the value. If you take a look, you will se that it not only emits the value of the field, but also the ValidityState (opens new window) and isValid for a quick identifier for validity. This should provide you with more information to manage form validation.

{
    isValid: true,
    validity: {
        badInput: false
        customError: false
        patternMismatch: false
        rangeOverflow: false
        rangeUnderflow: false
        stepMismatch: false
        tooLong: false
        tooShort: false
        typeMismatch: false
        valid: true
        valueMissing: false
    },
    value: ""
}

# Inline

You can move labels to be inline with the input.

<ks-form-field label="Username" inline></ks-form-field>

Note

The labels are positioned above the input field to improve usability and form completion (opens new window), but there are instances where having the label inline with the input is very useful. If you are using the inline property for aesthetic reasons, please reconsider.

# Debounce

Debouncing is a technique to help improve the performance of your application. The idea is to delay time-consuming tasks until the user is done doing what they are doing.

For example, if you have an input that performs a server-side action when the user types into an input, you may want to wait until the user is finished typing before you perform the action rather than each time they press a key.


<ks-form-field id="with_debounce" debounce="1000" label="With Debounce" />
<ks-form-field id="without_debounce" label="Without Debounce" />

<script>
    (function(){
        let withDebounce = document.getElementById('with_debounce');
        let withoutDebounce = document.getElementById('without_debounce');

        withDebounce.addEventListener('updated', function(e) {
            alert(`I waited until you finished entering: ${e.detail.value}`);
        });
        
        withoutDebounce.addEventListener('updated', function(e) {
            alert(`You entered: ${e.detail.value}`);
        });
    })();
</script>

# Accessibility

Accessibility was paramount when the Form Field component was designed. Most of the elements of this component utilize native browser features, but the features that have been added were designed with usability and accessibility in mind.

These features include:

  • Inputs all use IDs, names, and labels.
  • Labels are associated to with inputs using the for attribute.
  • Labels, Help Text, and Error Messages all display above the input to prevent the on-screen keyboard from blocking important text.
  • Error messages use role="alert" with the aria-live="assertive" to announce when validation errors occur
  • Error messages are accompanied with an icon to help users who cannot distinguish the error message based on color.
  • Default input validation occurs when the user leaves the field in order to prevent premature invalid responses. If a form field is invalid the validation will then occur on input to provide realtime feedback to the user when the issue is resolved.

# Properties

Property Attribute Description Type Default
autocomplete autocomplete check out the documentation (opens new window) for more information on available values and features string on
badInputErrorMessage bad-input-error-message the message that displays when the badInput validation is true string There was a problem processing your value.
defaultErrorMessage default-error-message the message that will display if invalid is set to true string The value entered is not valid.
disabled disabled disable form fields boolean false
inline inline move labels to be inline with input boolean false
helpText help-text additional information that displays below the form label string undefined
invalid invalid toggles whether the form is valid or not boolean false
label label the form field label string undefined
max max the max value for number and spin-box input types number undefined
maxErrorMessage max-error-message the error message that will display if the max value has been exceeded string Your value must be no greater than {max}.
maxlength maxlength the maximum number of characters a field will allow number undefined
maxlengthErrorMessage maxlength-error-message the error message that will display if the maxlength value is exceeded string Your value must be no more than {maxlength} characters.
min min the min value for number and spin-box input types number undefined
minErrorMessage min-error-message the error message that will display if the value is less than the min string Your value must be no less than {min}.
minlength minlength the minimum number of characters the value must be number undefined
minlengthErrorMessage minlength-error-message the error message that is displayed if the value length is less than the minlength string Your value must be at least {minlength} characters.
pattern pattern a regular expression used validate the value string undefined
patternErrorMessage pattern-error-message the error message displayed if the value does not match the pattern string There was a problem processing the value.
placeholder placeholder placeholder text that will display within the form field string undefined
required required toggles whether the form field is required boolean undefined
requiredErrorMessage required-error-message the error message displayed if required is true and is missing a value string This field is required.
requiredText required-text the text that will display when the required indicator is hovered or screen readers read the indicator string 'Required'
step step when using a spin-box the amount it will increment/decrement number undefined
stepErrorMessage step-error-message the error message that will display if the value is not divisible by the step value string This field is required.
tooltipText tooltip-text if set, an indicatory will appear and when hovered/focused on will display this content in a tooltip (supports HTML) string undefined
type type the input type "date", "email", "hidden", "number", "password", "search", "textarea", "tel", "text", or "url" 'text'
typeErrorMessage type-error-message the error message that will display if the value does not match the input type string Your value must be a valid {type}.
value value the input value number or string ''
validateOnInput validate-on-input toggles the validation timing at time of input boolean false

# Events

Event Description Type
blurred Adds event listener for the onBlur event of input field CustomEvent<any>
updated this event will execute each time the value is updated CustomEvent<{ isValid: boolean, validity: ValidityState; value: string \| number; }>

# Methods

# validate() => Promise<IFormFieldData>

# Returns

Type: Promise<IFormFieldData>