Documentation

Form validation

Code snippetsDesign guidelines

Summary

Form validation is used to provide an interface for validating form fields, and displaying feedback on problems.

Status

API status:experimental
Included in AUI core?Not in core You must explicitly require the web resource key.
Web resource key:com.atlassian.auiplugin:form-validation
Experimental since:5.5

Examples

Code

HTML

Create a field that you want to be validated

<form class="aui">
    <div class="field-group">
        <label for="demo-message-length">Input with validation on it</label>
        <input id="demo-message-length" class="text" type="text" data-aui-field data-aui-validate-minlength="10">
    </div>
</form>

Note the use of the data-aui-validate-minlength attribute. This attribute specifies minimum length of the input value (the length must be at least 10 characters, or validation will fail).

In addition, data-aui-field must be present for validation to occur.

This is enough for validation to be set up on the field – no further initialisation is necessary. The library will take care of binding events and adding markup to any input with a data-aui-validate-* data attribute.

Options

Markup configuration

Form validation arguments and options are expressed through markup.

Provided validators

Arguments for the provided validators are configured in data attributes beginning with the data-aui-validate-*prefix.

Data attributeDescriptionExample usage
  • data-aui-validate-minlength
  • data-aui-validate-maxlength
The length of the field's value must be less than or equal to the minlength, and greater than or equal to the maxlength.
<div class="fieldgroup">
    <input data-aui-field data-aui-validate-minlength="10" data-aui-validate-maxlength="140" class="text" type="text">
</div>
data-aui-validate-matchingfieldThe id of an input that must have a matching value
<div class="fieldgroup">
    <input id="field1" class="text" type="text">
    <input id="field2" data-aui-field data-aui-validate-matchingfield="field1" class="text" type="text">
</div>
data-aui-validate-doesnotcontainSome text that the value of the field cannot contain
<div class="fieldgroup">
    <input data-aui-field data-aui-validate-doesnotcontain="foo" class="text" type="text">
</div>
data-aui-validate-patternA regex pattern that the field must match
<div class="fieldgroup">
    <input data-aui-field data-aui-validate-pattern=".+@.+\.com" class="text" type="text">
</div>
data-aui-validate-requiredThis is a required field, and cannot have an empty value
<div class="fieldgroup">
    <input data-aui-field data-aui-validate-required="required" class="text" type="text">
</div>
  • data-aui-validate-min
  • data-aui-validate-max
The numerical value of this field must be greater than or equal to this minimum. Note that it is different to minlength / maxlength, as it compares a number's value, rather than a string's length.
<div class="fieldgroup">
    <input data-aui-field data-aui-validate-min="10" data-aui-validate-max="20" class="text" type="text">
</div>
data-aui-validate-dateformatA date format that this field must comply with. Can contain any separator symbols, or the following symbols, which represent different date components:
  • Y: Four digit year, eg. 2014
  • y: Two digit year, eg. 14
  • m: Numerical month, eg. 03
  • M: Abbreviated month, eg. Mar
  • D: Abbreviated day, eg. Mon
  • d: Numerical day, eg. 28
<!-- The below will match 03.28.2014 !-->
<div class="fieldgroup">
    <input data-aui-field data-aui-validate-dateformat="d.m.y" class="text" type="text">
</div>
  • data-aui-validate-minchecked
  • data-aui-validate-maxchecked
The number of checkboxes checked in this field must be greater than or equal todata-aui-validate-minchecked, and less than or equal todata-aui-validate-maxchecked
<form class="aui">
    <fieldset class="group" data-aui-field data-aui-validate-minchecked="1" data-aui-validate-maxchecked="2" data-aui-validate-when='click' data-aui-validate-displayfield="checkbox-wrapper">
        <legend><span>Checkboxes</span></legend>
        <div id="checkbox-wrapper" style="display: inline-block;">
            <div class="checkbox">
                <input class="checkbox" type="checkbox" name="checkbox-one" id="checkbox-one">
                <label for="checkbox-one">Receive email</label>
            </div>
            <div class="checkbox">
                <input class="checkbox" type="checkbox" name="checkbox-two" id="checkbox-two">
                <label for="checkbox-two">Receive push notification</label>
            </div>
            <div class="checkbox">
                <input class="checkbox" type="checkbox" name="checkbox-three" id="checkbox-three">
                <label for="checkbox-three">Receive in-app notification</label>
            </div>
        </div>
    </fieldset>
</form>
Provided validators messages

All of the above validators take an additional argument: data-aui-validate-...-msg. This sets a custom message that will be shown to the user when the validation requirement is violated.

Each argument is passed to AJS.format, with the value of the argument passed in as the first value.{0} will be replaced with the arguments value. For example,

<input type="text" data-aui-validate-pattern="http://www\..+\.com" data-aui-validate-pattern-msg="{0} is not a valid URL"</input>

The exception to this is data-aui-validate-matchingfield, which is passed the first field's argument in {0}and the second field's argument in {1}.

Validation options

Options affect the behaviour of all validators running on a field. They are configured in data attributes.

Data attributeDescriptionDefaultExample usage
data-aui-validate-whenThe event that will trigger validation. It can be any DOM event fired on the field, such as keyup or change, or a custom event that you will initiate yourself.

If you want to manually trigger validation, AJS.validator.validate($field) will run all validators that would be triggered on a field, without the data-aui-validate-when event occurring

change
<div class="fieldgroup">
    <input data-aui-field data-aui-validate-when="keyup" data-aui-validate-minlength="5" class="text" type="text">
</div>
data-aui-validate-watchfieldThe id of an additional element that can also trigger validation events (the event specified by data-aui-validate-when)Unspecified (only watches self)
<div class="fieldgroup">
    <input id="input-one" class="text" type="text">
    <input id="input-two" data-aui-field data-aui-validate-watchfield="input-one" data-aui-validate-minlength="5" class="text" type="text">
</div>
data-aui-validate-displayfield

The id of the element to decorate when fields become valid or invalid. Icons and tooltips will be displayed on this field, but validation events and logic will remain on the original field.

Unspecified (self)
<!-- Redirect decoration to the first field -->
<form class="aui">
    <div class="field-group">
        <input id="display-input" class="text" type="text">
    </div>
    <input type="hidden" data-aui-field data-aui-validate-displayfield="display-input" data-aui-validate-minlength="5" class="text" type="text">
</form>
<!-- Redirect decoration to the first checkbox label -->
<form class="aui">
    <fieldset class="group" data-aui-validate-minchecked="1" data-aui-validate-when='click' data-aui-field data-aui-validate-displayfield="first-label" data-aui-tooltip-position="top">
        <legend><span>Checkboxes</span></legend>
        <div class="checkbox">
             <input class="checkbox" type="checkbox" name="checkbox-one" id="checkbox-one">
             <label id="first-label" for="checkbox-one">Receive email</label>
        </div>
        <div class="checkbox">
            <input class="checkbox" type="checkbox" name="checkbox-two" id="checkbox-two">
            <label for="checkbox-two">Receive email</label>
        </div>
    </fieldset>
</form>
data-aui-validate-novalidateIf this argument is present, validation is completely disabled on the fieldNot present
<div class="field-group">
     <input data-aui-field validate-novalidate data-aui-validate-minlength="5" class="text" type="text">
 </div>
data-aui-tooltip-positionThe position that the the tooltip will be displayed on. Can be one of 'top', 'bottom' or 'side'."side"
<div class="field-group">
    <input data-aui-field data-aui-tooltip-position="top" data-aui-validate-minlength="5" class="text" type="text">
</div>

Form submission

To prevent users from submitting invalid forms, the form validation library will intercept submitevents that contain invalid, validating, or unvalidated elements. If the form is still being validated when a submit event occurs, submission will be delayed until validation completes.

When the form is submitted in a valid state, the event aui-valid-submit is triggered. If the submit event should be prevented, preventing the aui-valid-submit event will preventsubmit too.

<form id="valid-submit-form" class="aui">
     <div class="field-group">
          <input class="text" type="text" id="input-one" data-aui-field data-aui-validate-required="required">
     </div>
     <div class="field-group">
         <input class="text" type="text" id="input-two" data-aui-field data-aui-validate-max="10">
     </div>
     </fieldset>
 </form>
AJS.$('#valid-submit-form').on('aui-valid-submit', function(event) {
    alert('Data saved');
    event.preventDefault();
});

Field events

A number of additional events are triggered on fields using the form validation library.

Event nameDescriptionExample usage
aui-stop-typing

Triggered on a field when there have been no keyup events for some period of time. Can be used as the data-aui-validate-when option for validators.

<input data-aui-field data-aui-validate-when="aui-stop-typing" data-aui-validate-minlength="5" class="text" type="text">

Plugin validators

Additional validators can be registered and your own validators defined. They can be synchronous or asynchronous, and may validate or invalidate based on an element in any way.

//Register a plugin validator that ensures an input field must start with a certain sequence of characters
AJS.validator.register(['startswith'], function(field) {
    if (field.$el.val().indexOf(field.args('startswith')) === 0){
        field.invalidate(AJS.format('Input must start with {0}', field.args('startswith')));
    } else {
        field.validate();
    }
});

To use this plugin, simply use the markup in an input field

<div class="field-group">
    <input data-aui-field data-aui-validate-startswith="foo" type="text"/>
</div>
Registering a validator

The registerValidator function takes the following arguments

Argument nameDescription
trigger

The trigger that will cause a validator to be run on an element. Can be either an array of arguments to match, or a selector string to match.

If an array of validation arguments are provided, validation will be triggered on elements with the corresponding data attributes specified. For example, ['startswith', 'endswith'] will matchdata-aui-validate-startswith or data-aui-validate-endswith.

If a string is provided, validation will be triggered on elements that match this selector. For example, a trigger of '[aria-required]' will cause the validator to also be run when thearia-required attribute is present.

validationFunctionA function containing the logic of the validator. This function takes the argument field(see below for more information on this).
Writing the validator

The function validationFunction(field) is the core of a validator, containing the logic of whether or not a field is valid. It takes the following arguments

Argument nameDescription
fieldThe field that the validator is being asked to validate. It contains:
  • field.$el: a jQuery element of the field that validation has been requested on.
  • field.args: An accessor function to retrieve validation arguments from the element.arguments('startswith') will access the value for data-aui-validate-startswith
  • field.validate(): declare that this field has passed validation
  • field.invalidate(message): declare that this field has failed validation, and possibly show the user the message provided.

After performing whatever logic is necessary with the field.$el object to validate or invalidate, all code paths must execute either field.validate() or field.invalidate('message'). The reason given may be shown on the field as an error (see AJS.format() for formatting these strings).