Forms

Overview

Online form solution

As a Queensland Government franchise, agency or statutory body, you have access to an online form solution provided through Queensland Online. On the qld.gov.au website or franchise, an embedded form provided via this solution will inherit the SWE styles shown below.

Structure

In the SWE, we approach forms as a list of 'questions' and use an ordered list to structure it. A 'question' may include one or more form inputs/controls. If multiple inputs or controls are included, use a fieldset.

Forms may be divided into multiple sections and individual questions can be grouped.

Be sure to use an appropriate type attribute on all inputs (e.g. email for email address or number for numerical information).

Styles

Layout

Since Bootstrap applies display:block and width:100% to almost all form fields, forms will stack vertically by default.

For form layouts that require varied field widths, multiple columns, and additional alignment options, we suggest using the Bootstrap grid classes. Visit Bootstrap's form documentation to find more detailed guidance on form layout.

Text input

Inputs are used to capture short amounts (a single line) of text. Inputs should be accompanied by a label.

View example in Storybook

Textarea

Textareas are used for multiple lines of text, for example, a comments field.

View example in Storybook

Checkbox

Checkboxes allow users to select one or more items.

View example in Storybook

Checkbox custom theme

Implement this custom checkbox theme by using the class .rc-theme .

View example in Storybook

Code

<fieldset>
    <ol class="questions">
      <li>
        <fieldset>
          <ul class="choices compact rc-theme">
            <li>
              <input class="regular-checkbox big-checkbox" id="conditions-of-use1" value="true" name="conditions-of-use" type="checkbox">
              <label for="conditions-of-use1" class="rc-theme__label">
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
            <li>
              <input class="regular-checkbox big-checkbox" id="conditions-of-use2" value="true" name="conditions-of-use" type="checkbox">
              <label for="conditions-of-use2" class="rc-theme__label">
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
            <li>
              <input class="regular-checkbox big-checkbox" id="conditions-of-use4" value="true" name="conditions-of-use" type="checkbox" disabled="">
              <label for="conditions-of-use4" class="rc-theme__label">
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
          </ul>
        </fieldset>
      </li>
    </ol>
   
    <ol class="questions">
      <li>
        <fieldset>
          <ul class="choices compact rc-theme">
            <li>
              <input id="conditions-of-use5" class="regular-checkbox big-checkbox" value="true" name="conditions-of-use1" type="checkbox">
              <label for="conditions-of-use5" class="rc-theme__with-image">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="58" height="58" viewBox="0 0 32 32">
                  <path class="rc-theme__icon" d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
                </svg>
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
            <li>
              <input id="conditions-of-use6" class="regular-checkbox big-checkbox" value="true" name="conditions-of-use1" type="checkbox">
              <label for="conditions-of-use6" class="rc-theme__with-image">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="58" height="58" viewBox="0 0 32 32">
                  <path class="rc-theme__icon" d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
                </svg>
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
            <li>
              <input id="conditions-of-use8" class="regular-checkbox big-checkbox" value="true" name="conditions-of-use1" type="checkbox" disabled="">
              <label for="conditions-of-use8" class="rc-theme__with-image">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="58" height="58" viewBox="0 0 32 32">
                  <path class="rc-theme__icon" d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
                </svg>
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
          </ul>
        </fieldset>
      </li>
    </ol>
  </fieldset>

Radio

Radio inputs allow users to select one item at a time.

View example in Storybook

Radio custom theme

Implement this custom radio theme by using the class .rc-theme.

View example in Storybook

Code

<fieldset>
    
    <ol class="questions">
      <li>
        <fieldset>
          <ul class="choices compact rc-theme">
            <li>
              <input type="radio" name="current-test" value="Yes" required="required" id="current-test-yes-1">
              <label for="current-test-yes-1" class="rc-theme__label">
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
            <li>
              <input type="radio" name="current-test" value="No" required="required" id="current-test-no-1" >
              <label for="current-test-no-1" class="rc-theme__label">
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
            <li>
              <input type="radio" name="current-test" value="No" required="required" id="current-test-no-2" disabled>
              <label for="current-test-no-2" class="rc-theme__label">
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
          </ul>
        </fieldset>
      </li>
    </ol>
    
    <ol class="questions">
      <li>
          <p class="mb-0">Example with an SVG icon.</p>
          <fieldset>
          <ul class="choices compact rc-theme">
            <li>
              <input type="radio" name="current-test1" value="Yes" required="required" id="current-test-yes">
              <label for="current-test-yes" class="rc-theme__with-image">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="58" height="58" viewBox="0 0 32 32">
                  <path class="rc-theme__icon" d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
                </svg>
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
            <li>
              <input type="radio" name="current-test1" value="Yes" required="required" id="current-test-no">
              <label for="current-test-no" class="rc-theme__with-image">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="58" height="58" viewBox="0 0 32 32">
                  <path class="rc-theme__icon" d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
                </svg>
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
            <li>
              <input type="radio" name="current-test1" value="No" required="required" id="current-test-no1" disabled>
              <label for="current-test-no1" class="rc-theme__with-image">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="58" height="58" viewBox="0 0 32 32">
                  <path class="rc-theme__icon" d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
                </svg>
                <span class="rc-theme__label-desc">Lorem ipsum dolor sit amet.</span>
              </label>
            </li>
          </ul>
        </fieldset>
      </li>
    </ol>
    
</fieldset>

Select

Select provides a means to select a single item from a collapsible list. Use of select can help to reduce input errors and screen space. Use it when the customer does not need to see all the options to understand the question.

The first option in the list should be a prompt to make a selection and use the class 'placeholder'.

View example in Storybook

Date picker

View example in Storybook

Validation

Client-side validation is built into the SWE template. Fields are validated on change events and inline validation messages (shown with the label) are updated. All fields are validated on submit events and warnings are displayed in a summary placed before the form element.

View example in Storybook

Validation techniques

  • use the required="required" attribute on all required fields
  • use type="email" for email fields (note that more than one is not supported)
  • use .setCustomValidity( message ) for other validation
  • be sure to run custom validation on the best events:
    • on click for radio buttons and checkboxes
    • on change or blur for text fields, select boxes and textareas.

Example: Email address must be a qld.gov.au address

Code

<li>
  <label for="email">
    <span class="label">Email</span>
    <abbr title="(required)">*</abbr>
  </label>
  <input type="email" class="form-control" id="customer-email" name="emailField" required="required" />
</li>
  • Required fields is provided—use required="required"
  • Email validation is provided—use type="email"
  • Pattern validation is not yet supported (see more below).
  • Use custom script to verify email matches pattern.
  • Place the custom script after the global footer, or use jQuery's ready event.

Custom validation script

$( '#email' ).bind( 'change', function() {

      var emailPattern = /\.qld\.gov\.au$/,
          emailField = $( '#email' ),
          value = emailField.val()
      ;

      // if there is no value
      if ( value === '' ) {
          // clear the custom error
          emailField[ 0 ].setCustomValidity( '' );
          // required field validation will kick in

      // test if value matches pattern
      } else if ( emailPattern.test( value )) {
          // valid
          emailField[ 0 ].setCustomValidity( '' );

      } else {
          // invalid
          emailField[ 0 ].setCustomValidity( 'Must be a .qld.gov.au email address' );
      }

  });

Example: Required checkboxes

In HTML5, specifying required on any single checkbox requires the user to tick that box. This is useful for agreeing to terms and conditions. However, if you have a group of possible answers and only need the user to select one (or more), it will not work, and will force customers to tick every box.

To require one or more checkboxes are selected you must use custom validation. You can adapt the following code.

Place this script in the footer of the page:

(function( $ ) {
      'use strict';
      var minOneCheckboxGroups = [ 'flavours' ],
          seen = {},

      // check that at least one checkbox is checked
      minOneCheckboxCheckedCheck = function() {
          var checkboxes = $( this.form.elements[ this.name ] ),
              validitionMessage = ''
          ;
          // must have 1 item selected
          if ( checkboxes.filter( ':checked' ).length === 0 ) {
              validitionMessage = 'Must be completed';
          }
          // set validity on every checkbox in the group (UI isn't updated otherwise)
          checkboxes.each(function() {
              this.setCustomValidity( validitionMessage );
          });
      };
      // find checkboxes
      minOneCheckboxGroups = $( 'input' ).filter(function() {
          return $.inArray( this.name, minOneCheckboxGroups ) >= 0;
      });
      // initial validity for group
      minOneCheckboxGroups.each(function() {
          if ( ! seen[ this.name ] ) {
              seen[ this.name ] = true;
              minOneCheckboxCheckedCheck.apply( this );
          }
      })
      // setup event handler
      .on( 'change', minOneCheckboxCheckedCheck );
  }( jQuery ));

In your form, be sure to run this check when the form is submitted:

<form action="…" method="post" class="form" onsubmit="minOneCheckboxCheckedCheck();">

HTML5 constraint validation API notes

Validation is based off the HTML5 constraint validation API. The SWE template includes a polyfill for older browsers that do implement the API. The polyfill supports the following:

APIStatus Alternative tactics
.willValidate Not supported Assume all fields will be validated
.setCustomValidity( message ) Supported -
.validity.valueMissing Supported -
.validity.typeMismatch support for  @type=email  only use  .setCustomValidity for @type=url
.validity.patternMismatch Supported -
.validity.tooLong Not supported use  @maxlength  for  input  and  .setCustomValidity  for  textarea
.validity.rangeUnderflow Not supported use  .setCustomValidity
.validity.rangeOverflow Not supported use  .setCustomValidity
.validity.stepMismatch Not supported use  .setCustomValidity
.validity.customError Supported  (set by .setCustomValidity) -
.validity.checkValidity() Supported -
.validity.validationMessage support (supported for  valueMissingcustomError  and  typeMismatch  for  email ) .setCustomValidity  will set  validationMessage

Error messages

Error messages are used to notify the customer when a form field has not passed validation. Briefly describe the action the customer should take to correct each error before they submit the form again.

Use clear and positive language to explain what went wrong and how to fix it—focus on the solution, not the problem. Our suggestions are a guide only. Use messages that work for your customers.

Validation constraintSuggested error message
Required field is blank
  • First name is required
  • Licence number must be completed
Data is in the wrong format
  • Enter an email address in the correct format, like name@example.com
  • Enter a date in the correct format of DD/MM/YYYY
  • Enter a card number that is 16 digits long
Value outside range limits
  • Must be a year between 1920 and 1980
  • You must be over 18 years old
  • Must be more than 7
  • Must be less than 6

Hint text

Use hint text to provide inline instructions that help the customer understand and answer the question. Hints are optional.

Hint text is useful:

  • displaying required data formats (we recommended you use an example). If you support multiple data formats, display the most common one—do not describe them all
  • displaying example data
  • short instructions
  • links to more detailed help.

View example in Storybook

Further help information

Questions should be designed so customers can easily answer them. We should not expect customers to read help, but it can be provided when useful.

Help content must be published in either an aside on the form itself, or in a separate page.

You can link to help within a hint. The hint text should try to provide enough information if possible, with the help link providing supplemental and more detailed information. Links to help should use a class of help.

We recommend that help links open in a lightbox/pop-up.

View example in Storybook

Code

<!-- Hint text -->

<form class="qg-forms-v2">
    <ol class="questions">
        <li>
            <label for="car-make-model">
              <span class="label">Car make and model</span>
              <small class="hint">Example: Holden Commodore, Toyota Camry</small>
            </label>
            <input class="form-control" label="Car make and model" type="text"></input>
        </li>
    </ol>
</form>

<!-- Further help -->

<form class="qg-forms-v2">
    <ol class="questions">
        <li>
            <label for="card-security-code">
                <span class="label">Card security code</span>
                <small class="hint">3- or 4-digit code on the back of your card.
                  <a class="help" href="#">What is a card security code?</a>
                </small>
            </label>
            <div class="form-row">
              <div class="col-3 col-md-2">
                <input class="form-control" label="Card security code" type="text" maxlength="4" size="4"></input>
              </div>
            </div>
        </li>
    </ol>
</form>

reCAPTCHA

The SWE code for Google reCAPTCHA includes both the version 3 and version 2, the SWE footer feedback form uses the version 3.

Multiple reCAPTCHAs can be loaded on the same page.

To enable reCAPTCHA on a form with the default SWE Google reCAPTCHA key, set data-recaptcha=true.

You can set a custom key by using the attribute data-sitekey="KEY". For the feature to work, the combination server key must be used on the form submission handler.

View the GitHub repository for code implementation examples.

Additional usage guidance