Forms
Basic Inputs
Examples of standard form inputs used throughout the Control Portal. Add the .form-control
class to each input type to get proper formatting and alignment.
Labels & Accessibility
Provide labels to identity all form controls, including text fields, checkboxes, radio buttons, and drop-down menus. In most cases this is done by using the <label>
element, and should be used to describe the purpose of the form control.
A label for a form control helps everyone better understand its purpose. In some cases the purpose may be clear enough from the context when the content is rendered visually. In such cases a label can be hidden visually, though it still needs to be provided within the code to support other forms of presentation and interaction, such as for screen reader and speech input users. The recommended approach for hiding a label element, is to add the .sr-only
class to the label in the code. This avoids the visual redundancy for users who can derive the purpose from its visual context, but still provides screen reader support.
Text
<label class="sr-only" for="inputText">text input</label>
<input type="text" class="form-control" id="inputText" placeholder="Text Input">
Password
Examples of standard form inputs used throughout the Control Portal.
<label class="sr-only" for="inputPassword">password input</label>
<input type="password" class="form-control" placeholder="Password" id="inputPassword">
Textarea
<label class="sr-only" for="inputTextarea">textarea input</label>
<textarea class="form-control" rows="3" id="inputTextarea"></textarea>
Checkbox and Radios
<div class="checkbox">
<label>
<input type="checkbox" value="" /> Option 1
</label>
</div>
<div class="checkbox disabled">
<label>
<input type="checkbox" value="" disabled>
Option two is disabled
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
Option one is this and that—be sure to include why it's great
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="optionsRadios" id="optionsRadios2" value="option2">
Option two can be something else and selecting it will deselect option one
</label>
</div>
<div class="radio disabled">
<label>
<input type="radio" name="optionsRadios" id="optionsRadios3" value="option3" disabled>
Option three is disabled
</label>
</div>
Select Dropdowns
- If there is only one item in the select options, than that item should automatically be selected for the user.
- If there are multiple items in the list but there is a context for how the user has arrived, select the logical choice. For example, a user selects the create server button on the WA1 - US West (Seattle) Data Center Overview page, the logical choice for the Data Center dropdown would be WA1 - US West (Seattle).
- If there is no logical defaults then the user should be presented with a contextual message that tells them what to do as the first item in the list (e.g. ‘Select a Data Center...’)
<label class="sr-only" for="inputSelect">select dropdown</label>
<select class="form-control" id="inputSelect">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
Custom Pickers
Below are examples of extending radio or checkbox inputs to look and behave more like buttons by using cards to represent selectable items. This allows selectable options to comprise of text and imagery as a selectable unit (rather than text only), all while maintaining keyboard accessibility. Depending on the form and content of the options, your final implementation may require more styling to adjust for different widths and heights.
Single-Select Picker
The following example is for scenarios when one option may be chosen.
<!-- single-select (radio) -->
<div class="custom-picker">
<label for="radio1" class="control">
<input id="radio1" checked name='radioOptions' type="radio" value="centurylink">
<div class="card card-block hover-shadow hover-pointer">
<svg class="cyclops-icon md" aria-hidden="true"><use xlink:href='#icon-home' /></svg>
<h5>Single-Select Option 1</h5>
</div>
</label>
<label for="radio2" class="control">
<input id="radio2" name="radioOptions" type="radio" value="2">
<div class="card card-block hover-shadow hover-pointer">
<svg class="cyclops-icon md" aria-hidden="true"><use xlink:href='#icon-database' /></svg>
<h5>Single-Select Option 2</h5>
</div>
</label>
<label for="radio3" class="control" >
<input id="radio3" name="radioOptions" type="radio" value="3">
<div class="card card-block hover-shadow hover-pointer">
<svg class="cyclops-icon md" aria-hidden="true"><use xlink:href='#icon-global-network' /></svg>
<h5>Single-Select Option 3</h5>
</div>
</label>
<label for="radio4" class="control">
<input id="radio4" name="radioOptions" type="radio" value="4">
<div class="card card-block hover-shadow hover-pointer">
<svg class="cyclops-icon md" aria-hidden="true"><use xlink:href='#icon-infrastructure' /></svg>
<h5>Single-Select Option 4</h5>
</div>
</label>
</div>
Multi-Select Picker
The following example is for scenarios when more than one option may be chosen.
<!-- multi-select (checkboxes) -->
<div class="custom-picker">
<label for="checkbox1" class="control">
<input id="checkbox1" checked name='provider' type="checkbox" value="1">
<div class="card card-block hover-shadow hover-pointer">
<svg class="cyclops-icon md" aria-hidden="true"><use xlink:href='#icon-home' /></svg>
<h5>Multi-Select Option 1</h5>
</div>
</label>
<label for="checkbox2" class="control">
<input id="checkbox2" checked name="provider" type="checkbox" value="2">
<div class="card card-block hover-shadow hover-pointer">
<svg class="cyclops-icon md" aria-hidden="true"><use xlink:href='#icon-database' /></svg>
<h5>Multi-Select Option 2</h5>
</div>
</label>
<label for="checkbox3" class="control" >
<input id="checkbox3" name="provider" type="checkbox" value="3">
<div class="card card-block hover-shadow hover-pointer">
<svg class="cyclops-icon md" aria-hidden="true"><use xlink:href='#icon-global-network' /></svg>
<h5>Multi-Select Option 3</h5>
</div>
</label>
<label for="checkbox4" class="control">
<input id="checkbox4" name="provider" type="checkbox" value="4">
<div class="card card-block hover-shadow hover-pointer">
<svg class="cyclops-icon md" aria-hidden="true"><use xlink:href='#icon-infrastructure' /></svg>
<h5>Multi-Select Option 4</h5>
</div>
</label>
</div>
Hierarchy Pickers
When it is important to display the hierarchy of a collection (e.g. servers, groups, or organizations/accounts) in the selection process, use a hierarchy picker.
Single-Select Hierarchy Picker
If you want to allow the user to only pick one item use radio buttons.
<div class="picker">
<ol>
<li>
<label class="item-hover">
<input type="radio" name="group"/>
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-folder' /></svg> <span>Level 1a</span>
</span>
</label>
</li>
<li>
<label class="item-hover">
<input type="radio" name="group"/>
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-folder' /></svg> <span>Level 1b</span>
</span>
</label>
<ol>
<li>
<label class="item-hover">
<input type="radio" name="group"/>
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-folder' /></svg> <span>Level 2a</span>
</span>
</label>
</li>
</ol>
</li>
</ol>
</div>
Multi-Select Hierarchy Picker
If you want to allow the user pick many items use checkboxes.
<div class="picker">
<ol>
<li>
<label class="item-hover">
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-folder' /></svg> <span>Default Group</span>
</span>
</label>
<ol>
<li>
<label class="item-hover">
<input type="checkbox"/>
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-play' /></svg> <span>QA1DEVTEST01</span>
</span>
</label>
</li>
<li>
<label class="item-hover">
<input type="checkbox"/>
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-play' /></svg> <span>QA1DEVTEST02</span>
</span>
</label>
</li>
</ol>
</li>
<li>
<label class="item-hover">
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-folder' /></svg> <span>Web Servers</span>
</span>
</label>
<ol>
<li>
<label class="item-hover">
<input type="checkbox" disabled/>
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-stop' /></svg> <span>QA1DEVSRVR01</span>
</span>
</label>
</li>
<li>
<label class="item-hover">
<input type="checkbox"/>
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-play' /></svg> <span>QA1DEVSRVR02</span>
</span>
</label>
</li>
<li>
<label class="item-hover">
<input type="checkbox"/>
<span class="content">
<svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-play' /></svg> <span>QA1DEVSRVR03</span>
</span>
</label>
</li>
</ol>
</li>
</ol>
</div>
One Label with Stacked Inputs
By default, inputs will automatically stack when placed in a single column.
<form class="form-horizontal">
<fieldset>
<div class="form-group">
<label class="col-sm-3 control-label">nodes</label>
<div class="col-sm-6">
<label class="sr-only" for="inputTextNode1">node 1</label>
<input type="text" id="inputTextNode1" class="form-control" placeholder="ip address">
<label class="sr-only" for="inputTextNode2">node 2</label>
<input type="text" id="inputTextNode2" class="form-control" placeholder="ip address">
<label class="sr-only" for="inputTextNode3">node 3</label>
<input type="text" id="inputTextNode3" class="form-control" placeholder="ip address">
<label class="sr-only" for="inputTextNode4">node 4</label>
<input type="text" id="inputTextNode4" class="form-control" placeholder="ip address">
</div>
</div>
</fieldset>
</form>
One Label with Adjacent Inputs
When it is more appropriate to adjacently align inputs within a .col-*
, add a .w*
to the .form-control
set the width based on a percentage of the parent. Widths are avaialbe in increments of 10, starting at 10%.
<form class="form-horizontal">
<fieldset>
<div class="form-group">
<label class="col-md-3 control-label">nodes</label>
<div class="col-md-9 col-sm-12">
<ul class="list-unstyled">
<li class="m-b-xs">
<label class="sr-only" for="inputTextAdjacentNode1">node 1</label>
<toggle class="d-inline-block m-r-xxs"></toggle>
<input type="text" id="inputTextAdjacentNode1" class="form-control w40" placeholder="ip address">
<label class="sr-only" for="inputTextAdjacentPort1">node port 1</label>
<input type="text" id="inputTextAdjacentPort1" class="form-control w20 m-t-0" placeholder="port">
<div class="w10">
<button class="btn btn-default btn-icon"><svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-times' /></svg></button>
</div>
</li>
...
</ul>
</div>
</div>
</fieldset>
</form>
Custom Controls
For more complex controls that require more than simple markup, we utilize the jQuery UI Widget pattern. This does not mean that we require jQuery UI, however, we simply include and use this pattern to provide a consistent API for you to interact with. These widgets allow us to use Cyclops to embellish and extend the standard markup to provide a richer user experience.
Toggle
<input id="customToggle" type="checkbox" />
var toggleWidget = $("#customToggle").toggle({ onChange: function(event, data) { // Called every time the checked state changes. } }); // Get the current checked state toggleNode.toggle("checked"); // Set the state to checked toggleNode.toggle("checked", true);
Range
<input id="customRange" type="range" min="1" max="100" step="10" />
var rangeNode = $("#customRange").range({ valueChange: function(evt, data){ // Called every time the value changes // data.value to access the current value } }); // Get the current value rangeNode.range("value"); // Set the current value rangeNode.range("value", 10);
Disabled Inputs
Add the disabled
attribute on an input to prevent user interactions. Disabled inputs appear lighter and add a not-allowed
cursor.
<input type="text" class="form-control" id="disabledInput" placeholder="Disabled Text Input" disabled>
Disabled Fieldset
<form>
<fieldset disabled>
<div class="form-group">
<label for="disabledTextInput">Disabled input</label>
<input type="text" id="disabledTextInput" class="form-control" placeholder="Disabled input">
</div>
<div class="form-group">
<label for="disabledSelect">Disabled select menu</label>
<select id="disabledSelect" class="form-control">
<option>Disabled select</option>
</select>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Can't check this
</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</fieldset>
</form>
Basic Form
Individual form controls automatically receive some global styling. All textual <input>
, <textarea>
, and <select>
elements with .form-control
are set to width: 100%; by default. Wrap labels and controls in .form-group
for optimum spacing.
- Labels should have a
for
attribute that points to theid
of an input type. It is only allowed to point to input types not any element - The fieldset legend name should be useful not just
edit
orcreate
- Optional fields are denoted not required fields.
- Tab order should be logical and visit ever valid field (e.g. do not tab to disabled items)
- Items that are not editable are presented as paragraph tags not disabled inputs
<form>
<div class="form-group">
<label for="basicFormEmail">Email address</label>
<input type="email" class="form-control" id="basicFormEmail" placeholder="Email">
</div>
<div class="form-group">
<label for="basicFormPassword">Password</label>
<input type="password" class="form-control" id="basicFormPassword" placeholder="Password">
</div>
<div class="form-group">
<label for="basicFormFileInput">File input</label>
<input type="file" id="basicFormFileInput">
<p class="help-block">Example block-level help text here.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
<button class="btn btn-link">cancel</button>
</form>
Inline Forms
Use .inline-form
to display labels and form inputs on a single row. This is useful for confirmation dialogs that offer additional options (e.g. delete a database, but create a backup before it's deleted).
<form class="form-inline">
<div class="form-group">
<label for="inputEmail">email</label>
<input type="text" class="form-control" id="inputEmail" placeholder="email">
</div>
<div class="form-group">
<toggle></toggle>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> remember me
</label>
</div>
<div class="radio">
<label>
<input type="radio"> radio me
</label>
</div>
<button type="submit" class="btn btn-primary">sign in</button>
</form>
Horizontal Form
Horizontal forms rely on the Grid System to align form labels and inputs horizontally. These forms used throughout the Control Portal to create new entities, such as servers, appfog apps, and policies.
Add a visual separator to the form submission buttons by adding .form-submit
to the .form-group
container.
<form class="form-horizontal">
<div class="form-group">
<label for="horizontalFormEmail" class="col-sm-3 control-label">Email</label>
<div class="col-sm-9">
<input type="email" class="form-control" id="horizontalFormEmail" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="horizontalFormPassword" class="col-sm-3 control-label">Password</label>
<div class="col-sm-9">
<input type="password" class="form-control" id="horizontalFormPassword" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
</div>
</div>
<div class="form-group form-submit">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-default">sign in</button>
<button class="btn btn-link">cancel</button>
</div>
</div>
</form>