Octopus users often use forms to add, edit, and configure entities (for example: Tenants, Workers, Environments) and settings. Forms can be lengthy and offer numerous possible paths for setup. To ensure users know which information must be provided (and in what format) to achieve their goals, we design forms to be highly usable and explicit.
When to use forms
Forms are a way of capturing user input, whether it’s free-form typing or a selection of values. Use forms when your primary goal is to:
- Gather data: let users to provide information that’s necessary for using Octopus successfully
- Configure and customize: allow users to set up Octopus in a way that’s most relevant to them
Form anatomy
A form is a composition of form components (including contextual help) and validation:
|
Element |
Description |
Optional? |
|---|---|---|
|
1. Field label |
Mandatory textual label used to describe the form field to guide users in filling it. |
No |
|
2. Popover trigger |
Icon used to signify a popover trigger in the context of forms, where helper text is not sufficient or suitable to provide additional information. |
Yes |
|
3. Form validation |
Icon and text used when validating user form input to provide advice on fixing input errors and confirmation when they are addressed. |
Yes |
|
4. Required or optional marker |
Textual label used to denote if a field is required or optional. Marker’s copy is not changeable. |
Yes |
|
5. Placeholder |
Text providing an example of expected user input. |
Yes |
|
6. Helper text |
Additional description helping users provide the right input, if the field label is insufficient. |
Yes |
Always use labels
All form fields should have descriptive labels that are:
- Maximum three words long (consider help text if you’re struggling with the limit)
- Written in sentence case (except for feature or entity names)
- Without a colon at the end
We don’t use placeholders as replacements for labels as they lead to numerous accessibility issues, strain short-term memory and cause mistakes when filling forms (according to Nielsen Norman Group research).
Use appropriate form fields
Tailor form fields to the type of input that’s expected. HTML natively supports numerous, semantic input types that guide users in providing the desired values and provide additional functionality, such as password masking.
Field alignment
To ensure readability and the ease of scanning forms:
- Content flows from top to bottom and is left-aligned
- Labels are placed above the inputs (in rare cases, they might be located to the left of the input—this behavior will be specified at a component level)
- The button container is aligned to the right
- The primary button is positioned to the right of its container
- In multi-column forms, elements are baseline aligned
Field sizing
When sizing form fields, consider the following:
- The amount of expected user input
- Sizing of the other fields in a form
If a user has to provide a double-digit number, there’s no need to use input that spans most of the screen. However, we discourage having forms with inputs of many inconsistent sizes. Balance these two approaches to create a uniform experience.
Single and multi-column forms
We recommend single-column forms for the majority of use cases. When working with a single-column form layout, consider setting a minimum and maximum width for the form element to ensure it’s responsive to viewport changes and form elements aren’t excessively wide but adapt to the inserted data.
While multi-column forms make the flow of forms hard to follow and can lead to user confusion (according to Nielsen Norman Group research), there are limited use cases when they can be helpful.
Form placement
Where you place a form depends on its length and the context of the action a user intends to perform:
|
Form placement |
When to use |
Examples |
|---|---|---|
|
On page |
For long, complex forms (single and multi-step). |
Creating a Machine Policy, Creating a Deployment Target. |
|
Dialog |
For short forms (less or equal to 5) connected to editing and management tasks. |
Adding a Project Group, Generating User Invites. |
|
Drawer |
For long (less or equal to 10), complex forms connected to editing and management tasks. |
Creating a Git Credential in Step Templates. |
Form interaction model based on user intention
How forms are displayed and interacted with depends on the user goal, type of data provided, form complexity, and how they fit into the greater context of a user journey. Depending on these factors, we differentiate the following experiences:
- Form Edit: when form elements are displayed for the user to provide necessary information
- Form Summary View: when a summary of information provided is displayed in primarily textual manner for ease of scanning
Not every use case requires a preview of supplied data—in certain scenarios, displaying a form at all times is acceptable. Check the following decision tree and visualization to guide your approach:
Form sectioning
Form fields that are closely related should be visually grouped together. When grouping form elements:
- Place them in the same section with a short legend to describe the groups’ contents (for example: Billing information, User permissions, Branch settings)
- Optionally, add a short description in a paragraph at the top of the section, preceding the form elements
- Use static or interactive sectioning depending on the number of form elements present and the placement of the form:
|
Method |
No sectioning |
Static sectioning |
Interactive sectioning |
|---|---|---|---|
|
Preview |
|
|
|
|
Number of elements |
Less or equal to 5 |
Less or equal to 10 |
More than 10 |
|
Description |
Form elements are always visible, without additional sectioning. |
Section contents are always visible. |
Section contents can be shown or hidden. By default, sections marked as optional and pre-filled should be closed. |
|
Scope |
On page, Dialogs, Drawers |
On page, Drawers |
On page |
Mark required, optional and pre-filled fields and sections
We always provide explicit guidance on which information is required to ensure users complete forms successfully. Form elements are marked depending on the composition of each form and their sections:
|
|
All required |
All optional |
Majority optional |
Majority required |
All pre-filled |
Some pre-filled |
|---|---|---|---|---|---|---|
|
Section heading marker |
(required) |
(optional) |
N/A |
N/A |
(pre-filled) |
N/A |
|
Form element marker |
N/A |
N/A |
(required) |
(optional) |
(default) |
(default) |
Whole sections are marked as (optional), (required) or (pre-filled) only if all fields within meet that criteria. If the majority of fields or sections are required, only mark optional ones with the (optional) label. While if the majority of fields or sections are optional, only mark the required ones with the (required) label.
Always mark required fields with both required and aria-required attributes. Avoid an excessive number of optional form fields. If there’s a case when it’s not avoidable, consider grouping optional fields under the same form section. If a user changes one of the pre-filled choices within a section, the pre-filled marker in the section legend should be removed.
Providing contextual help
When form fields aren’t self-explanatory or are less familiar to users, we provide contextual help to prevent errors in configuration. The way we provide help depends on the context of information shared:
|
Method |
Placeholder |
Helper Text |
Popover |
|---|---|---|---|
|
Preview |
|
|
|
|
When to use |
Providing non-essential, supplementary example of field contents. Always prefixed with “e.g.”. |
Ensuring the user provides accurate information. Can include example input ( always prefixed with “e.g.”). |
Providing contextual help by introducing new concepts or features. |
|
Maximum length |
3 words. |
1 short sentence. |
1-2 short sentences (max. 3 lines of text) with an optional title, image, video or a documentation link. |
|
Example |
e.g. Frontend Team |
Only Username/Password Accounts may be selected. |
During a deployment, this step will run on targets matching any of these target tags. Specify one or more tags here, and add them to Deployment Targets later. |
Disabling and hiding form elements
When to use a disabled button
Filled forms (editing)
There might be limited, specific use cases when adding a disabled attribute is warranted. One of them is disabling a button when editing an already filled form until changes are made to either of the form fields.
Another one is temporarily disabling a button when submitting takes a noticeable amount of time and we want to prevent double submission of the form. In those cases, the change of state should be appropriately visualised and communicated through micro copy.
Permissions requirement
At times, we may use a disabled state to indicate that an action is unavailable because the user requires permissions to perform such an action.
In this case:
- The original button label should remain the same.
- On hover, a tooltip should display the following copy to explain why the action is disabled: “You don’t have permissions to perform this action.”
|
Option |
Description |
|---|---|
|
1. Has permissions |
Button is displayed in its rest state. |
|
2. Does not have permissions |
Button is disabled. The original button label should remain the same. On hover, a tooltip explains why the action is disabled. |
Prerequisite action
We may also use a disabled state to indicate that the user cannot progress because they are blocked by a required prior action; that is, a prerequisite action necessary to complete a flow.
It follows the same pattern explained above; however, the copy should be customized per use case.
In the example below, the user has not completed a prerequisite action of approving the deployment, so they cannot deploy.
When not to use a disabled button
Unfilled forms (adding)
Submit buttons should be enabled by default when filling out a form for the first time. Submit buttons with a disabled attribute introduce numerous negative impacts for accessibility and user experience, such as:
- Creating obstacles for people using screen readers or keyboards to navigate forms.
- Reducing readability as disabled component variants often have insufficient contrast.
- Fostering confusion by creating an impression that something is off without an explanation.
Hiding form elements
By default, we don’t hide form elements that users don’t have access to due to roles and permissions. Instead, we use the disabled HTML attribute to show that the element exists, but the user doesn’t have permissions to edit. In those cases, we also provide contextual messages to communicate why a field isn’t editable.
If the disabled form field has already been filled, we use the readonly HTML attribute instead. In most cases, a form will be either fully editable or not editable at all depending on user permissions.
Progressive disclosure of form fields
Progressive disclosure is an interaction design strategy for reducing cognitive load when faced with complex interfaces. In the context of forms, we recommend:
- hiding elements that are available only when the user makes a specific selection (most commonly using Radio Group or Checkbox components)
- displaying additional form elements based on a selection below the field (not nested within it), to accommodate multiple levels of nesting and maintain the flow of the form
Validation and error messaging
Clear and timely messaging is critical in guiding users through resolving issues while filling forms. We always provide concise information about what happened and what the steps should be followed for positive resolution.
Validation states
There are two types of validation states for selected form fields:
- Error: When content is invalid and needs to be corrected, this state is always accompanied by a reason for the invalid input and steps to resolve it.
- Success: When content is valid. Messaging doesn’t usually accompany this state unless client-side validation is used to live-check the input (e.g. checking if a provided URL is valid).
Server-side validation
Server-side validation is currently the primary way of validating forms in Octopus. The entire form should be validated on submission. When a form fails validation:
- Display a summary of errors referencing invalid form fields and scroll to the summary to ensure it’s in the viewport
- Use inline validation states on erroneous fields
- If an error cannot be tied to a particular field, use a top form level message (same approach as when amount of errors exceeds 3)
- Mark invalid form fields with aria-invalid=true to ensure invalid fields are properly announced by assistive technology
- Tie inline messaging for invalid fields by providing an id in aria-describedby attribute
Client-side validation
Traditionally, client-side validation occurs in real time (as users interact with form fields). Currently, we use this type of validation only in Channels area (when designing package version rules: see “Design rule” action and enter invalid Sample Versions), and we encourage using server-side validation instead. If client-side validation is the most suitable solution, ensure consistency between front-end and back-end implementation of the validation rules.
Another way of defining client-side validation is using the right component with the right attributes to enforce correct data input (for example, using input type="number" with min and max values when expecting numeric values within a certain range). The use cases for each component can be found in their documentation.
Accessibility
- Allow tabbing through form fields in logical order. This benefits visually impaired users who might be using assistive technologies.
- Auto focus into the first field by default. This ensures people can quickly orient themselves and tab through the form elements.
- Never turn off the submission button, even if all form fields haven’t been filled out yet. Use validation and error messaging to guide people in providing expected data.
See WCAG Form Tutorial for specific, in-depth instructions about creating accessible forms.