Forms
Create a variety of forms to collect user input.
Styles
The FMS Design System delivers five (5) form element styles depending on your need:
Form validation
The FMS Design System leverages HTML5 and Bootstrap form validation. Examples of custom validation and server side validation are available at the bottom of this page.
Text input
A text input control allows for collecting text-based values from the user. The default state of a text input is shown below.
<form>
<div class="form-row">
<div class="form-group hide-icon col-md-4 mb-3">
<label for="defaultTextInput">Default State</label>
<input
type="text" class="form-control"
id="defaultTextInput"
placeholder="placeholder"
autocomplete="off">
</div>
<div class="form-group hide-icon col-md-4 mb-3">
<label for="defaultTextInputIconText">Default State</label>
<div class="input-group">
<span class="prepend-placeholder"></span>
<input
type="text" class="form-control"
id="defaultTextInputIconText"
autocomplete="off">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
<div class="form-group col-md-4 mb-3">
<label for="defaultTextInputTextIcon">Default State</label>
<div class="input-group">
<input
type="text" class="form-control"
id="defaultTextInputTextIcon"
autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-search"></i>
</span>
</div>
</div>
</div>
</div>
</form>
Configuration options
Further configuration can be made to this default input:
- adding validation states
- disabling the input
- rendering the input read-only
- adding hint text
- adjusting the positioning of labels (vertical or horizontal)
For general information on optional form configuration, like adding an icon to your form input control or updating feedback text, see Bootstrap Forms documentation.
For accessibility purposes, icons indicating validation state are included as part of the design system.
Validation examples
Invalid
<form>
<div class="form-row">
<div class="form-group hide-icon col-md-4 required">
<label for='is-invalid-text' class="py-0">Invalid State</label>
<input
type="text" class="form-control is-invalid"
id='is-invalid-text'
required
placeholder="placeholder"
autocomplete="off">
<div class="form-feedback">
<div class="invalid-feedback">Example invalid message text</div>
</div>
</div>
<div class="form-group hide-icon col-md-4 required">
<label for='is-invalid-icon-text' class="py-0">Invalid State</label>
<div class="input-group">
<span class="prepend-placeholder"></span>
<input
type="text" class="form-control is-invalid"
id='is-invalid-icon-text'
required
autocomplete="off">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
<div class="form-feedback">
<small class="invalid-feedback">Example invalid message text</small>
</div>
</div>
</div>
<div class="form-group col-md-4 required">
<label for='is-invalid-text-icon' class="py-0">Invalid State</label>
<div class="input-group">
<input
type="text" class="form-control is-invalid"
id='is-invalid-text-icon'
required
autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-search"></i>
</span>
</div>
<div class="form-feedback">
<small class="invalid-feedback">Example invalid message text</small>
</div>
</div>
</div>
</div>
</form>
Disabled
A disabled text input means information in the element isn’t applicable or can’t be edited.
To disable a text input, assign the disabled
attribute the input
.
<form>
<div class="form-row">
<div class="form-group hide-icon col-md-4 mb-3">
<label for="disabledTextInput" class="py-0">Disabled State</label>
<input
type="text" class="form-control"
id="disabledTextInput"
disabled
placeholder="placeholder"
autocomplete="off">
</div>
<div class="form-group hide-icon col-md-4 mb-3">
<label for="disabledTextInputIconText" class="py-0">Disabled State</label>
<div class="input-group">
<input
type="text" class="form-control"
id="disabledTextInputIconText"
disabled
autocomplete="off">
<span class="prepend-placeholder"></span>
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
<div class="form-group col-md-4 mb-3">
<label for="disabledTextInputTextIcon" class="py-0">Disabled State</label>
<div class="input-group">
<input
type="text" class="form-control"
id="disabledTextInputTextIcon"
disabled
autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-search"></i>
</span>
</div>
</div>
</div>
</div>
</form>
Read-only
A read-only text input means information in the element can’t edited.
To make a text input read-only, assign the readonly
attribute to the input
.
<form>
<div class="form-row">
<div class="form-group hide-icon col-md-4 mb-3">
<label for="readonlyTextInput" class="py-0">Readonly State</label>
<input
type="text" class="form-control"
id="readonlyTextInput"
readonly
placeholder="placeholder"
autocomplete="off"
value="A readonly text value"
aria-readonly="true">
</div>
<div class="form-group hide-icon col-md-4 mb-3">
<label for="readonlyTextInputIconText" class="py-0">Readonly State</label>
<div class="input-group">
<span class="prepend-placeholder"></span>
<input
type="text" class="form-control"
id="readonlyTextInputIconText"
readonly
autocomplete="off"
value="A readonly text value"
aria-readonly="true">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
<div class="form-group col-md-4 mb-3">
<label for="readonlyTextInputTextIcon" class="py-0">Readonly State</label>
<div class="input-group">
<input
type="text" class="form-control"
id="readonlyTextInputTextIcon"
readonly
autocomplete="off"
value="A readonly text value"
aria-readonly="true">
<div class="input-group-append">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-search"></i>
</span>
</div>
</div>
</div>
</div>
</form>
Hint text
Hint text provides guidance on how to fill out a field. The following attributes define hint text:
div.form-feedback
creates a uniform space for hint textsmall.form-text .text-muted
controls formatting and display of hint text
<form>
<div class="form-row">
<div class="form-group hide-icon col-md-4">
<label for="hintTextInput" class="py-0">Default State</label>
<input
type="text" class="form-control"
id="hintTextInput"
placeholder="placeholder"
autocomplete="off">
<div class="form-feedback">
<small class="form-text text-muted">Example hint message text</small>
</div>
</div>
<div class="form-group hide-icon col-md-4">
<label for="hintTextInputIconText" class="py-0">Default State</label>
<div class="input-group">
<span class="prepend-placeholder"></span>
<input
type="text" class="form-control"
id="hintTextInputIconText"
autocomplete="off">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
<div class="form-feedback">
<small class="form-text text-muted">Example hint message text</small>
</div>
</div>
<div class="form-group col-md-4">
<label for="hintTextInputTextIcon" class="py-0">Default State</label>
<div class="input-group">
<input
type="text" class="form-control"
id="hintTextInputTextIcon"
autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-search"></i>
</span>
</div>
</div>
<div class="form-feedback">
<small class="form-text text-muted">Example hint message text</small>
</div>
</div>
</div>
</form>
Vertical label
Vertical labels display above the input form. This approach is ideal if the width of the page or column containing the input is narrow.
Assign .form-row
to each row within the form (typically a div
element) to display a vertical label.
<form>
<div class="form-row">
<div class="form-group hide-icon col-md-4 mb-3">
<label for="exampleFormControlInput1" class="py-0">Label</label>
<input
type="text" class="form-control"
id="verticalLabelTextInput"
placeholder="placeholder"
autocomplete="off">
</div>
<div class="form-group hide-icon col-md-4 mb-3">
<label for="exampleFormControlInput1" class="py-0">Label</label>
<div class="input-group">
<span class="prepend-placeholder"></span>
<input
type="text" class="form-control"
id="verticalLabelTextInputIconText"
autocomplete="off">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
<div class="form-group col-md-4 mb-3">
<label for="exampleFormControlInput1" class="py-0">Label</label>
<div class="input-group">
<input
type="text" class="form-control"
id="verticalLabelTextInputTextIcon"
autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-search"></i>
</span>
</div>
</div>
</div>
</div>
</form>
Horizontal label
Horizontal labels display beside the input element. This approach is ideal if the page or column containing the input is wide enough to accommodate a horizontal label.
Assign .form-inline
to the form
element to display a horizontal label.
<form class="form-inline">
<div class="form-group mr-3 mb-3">
<label for="horizontalLabelTextInput" class="px-0 mr-2">Label</label>
<input
type="text"
class="form-control"
id="horizontalLabelTextInput"
placeholder="placeholder"
autocomplete="off">
</div>
<div class="form-group mr-3 mb-3">
<label for="horizontalLabelTextInputIconLabel" class="px-0 mr-2">Label</label>
<div class="input-group">
<span class="prepend-placeholder"></span>
<input
type="text"
class="form-control"
id="horizontalLabelTextInputIconLabel"
placeholder="placeholder"
autocomplete="off">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
<div class="form-group mb-3">
<label for="horizontalLabelTextInputLabelIcon" class="px-0 mr-2">Label</label>
<div class="input-group">
<input
type="text"
class="form-control"
id="horizontalLabelTextInputLabelIcon"
placeholder="placeholder"
autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-search"></i>
</span>
</div>
</div>
</div>
</form>
Textarea
Textareas are like a Text input element in that they can collect text-based values, but textareas can collect more characters than text inputs. Like text inputs, textareas can have placeholder text to guide the user.
The following example demonstrates the default textarea, with no input or validation applied.
<form>
<div class="form-row">
<div class="col-sm-12">
<div class="form-group">
<label for="exampleTextarea" class="py-0">Default State</label>
<textarea class="form-control" id="exampleTextarea" placeholder="Placeholder" aria-describedby="exampleTextareaHelpDefault"></textarea>
<div class="text-right form-feedback">
<small id="exampleTextareaHelpDefault" class="form-text text-muted">
102/500 characters
</small>
</div>
</div>
</div>
</div>
</form>
Configuration options
Further configuration can be made to this default input:
- adding validation states
- disabling the textarea
- rendering the textarea read-only
- displaying form content inline
For general information on optional form configuration, like adding an icon to your form input control or updating feedback text, see Bootstrap Forms documentation.
For accessibility purposes, icons indicating validation state are included as part of the design system.
Validation examples
Invalid
<form>
<div class="form-group required">
<label for="exampleTextareaInvalid" class="py-0">Invalid State</label>
<textarea class="form-control is-invalid" required id="exampleTextareaInvalid" aria-describedby="exampleTextAreaHelpInvalid"></textarea>
<div class="form-feedback">
<small id="exampleTextAreaHelpInvalid" class="invalid-feedback">Example invalid hint text</small>
</div>
</div>
</form>
Disabled
Disabled textareas are unable to be edited by users. Any information in a disabled textarea won’t be submitted when users submit a form.
To disable a textarea, add the disabled
attribute to the textarea
element.
<form>
<div class="form-row">
<div class="col-sm-12">
<div class="form-group">
<label for="exampleTextareaDisabled" class="py-0">Disabled State</label>
<textarea class="form-control" id="exampleTextareaDisabled" aria-describedby="exampleTextAreaHelpDisabled" aria-disabled="true" disabled></textarea>
<div class="text-right form-feedback">
<small id="exampleTextAreaHelpDisabled" class="form-text text-muted">Example disabled hint text</small>
</div>
</div>
</div>
</div>
</form>
Read-only
Read-only form fields prevent users from entering any information into a textarea element, but the information in read-only textareas are submitted when users submit a form.
To make a textarea read-only, add the readonly
attribute to the textarea
element.
<form>
<div class="form-row">
<div class="col-sm-12">
<div class="form-group">
<label for="exampleTextareaReadonly" class="py-0">Readonly State</label>
<textarea class="form-control" id="exampleTextareaReadonly" aria-describedby="exampleTextAreaHelpReadonly" aria-readonly="true" readonly>Some read-only text</textarea>
<div class="text-right form-feedback">
<small id="exampleTextAreaHelpDisabled" class="form-text text-muted">Example readonly hint text</small>
</div>
</div>
</div>
</div>
</form>
Inline
By including the .form-inline
class on your form tag, you can make your form label, control, and hint text appear together, on the same line. See Bootstrap’s inline form documentation for more information.
<form class="form-inline">
<div class="form-group">
<label for="exampleInlineTextarea" class="py-0">Default State</label>
<textarea class="form-control mx-2" id="exampleInlineTextarea" aria-describedby="exampleTextareaHelpInline"></textarea>
</div>
</form>
Select
A select control allows users to select one option from a predefined list of inputs. The select control has two main elements: a toggle control to open and close a menu and a list of menu options or values. When the user selects an menu option from the list, the selection appears in the toggle. Hint text can be provided to assist users with their selection process.
Select controls can be used in forms on full pages, in modals, or on side panels. Don’t nest select menus or use them to display overly complex information. Keep options as straightforward as possible.
Consider using a select over a dropdown if most of your experience is form-based or frequently used on mobile devices. The native select works more easily with a native form and is easier to use on a mobile device.
The following example demonstrates the default select menu, with no user input or validation applied.
<form>
<div class="form-row">
<div class="form-group col-md-6 mb-3">
<label for="defaultSelectText" class="py-0">Default State</label>
<select class="custom-select" id="defaultSelectText">
<option>Highlight</option>
<option>Supervisor best practice summary dashboard</option>
<option>Space Summary</option>
</select>
</div>
<div class="form-group col-md-6 mb-3">
<label for="defaultSelectIconText" class="py-0">Default State</label>
<div class="input-group left-icon">
<select class="form-control custom-select" id="defaultSelectIconText">
<optgroup label="Published">
<option>Icon Text</option>
<option>Supervisor best practice summary dashboard</option>
</optgroup>
<optgroup label="Unpublished">
<option>Space Summary</option>
</optgroup>
</select>
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
</div>
</form>
Configuration options
Further configuration can be made to this default input:
- adding validation states
- disabling select controls
- adding hint text
- adding vertical labels
- adding horizontal labels
For general information on optional form configuration, like adding an icon to your form input control or updating feedback text, see Bootstrap Forms documentation.
For accessibility purposes, icons indicating validation state are included as part of the design system.
Validation examples
Invalid
<form>
<div class="form-row">
<div class="form-group hide-icon col-md-6 required">
<label for='invalid-Text' class="py-0">Invalid State</label>
<select
class="custom-select is-invalid"
id="invalid-Text"
required>
<option>Highlight</option>
<option>Supervisor best practice summary dashboard</option>
<option>Space Summary</option>
</select>
<div class="form-feedback">
<small class="invalid-feedback">
Example invalid message text
</small>
</div>
</div>
<div class="form-group col-md-6 required">
<label for='invalid-Icontext' class="py-0">Invalid State</label>
<div class="input-group left-icon">
<select
class="custom-select is-invalid"
id="invalid-Icontext"
required>
<optgroup label="Published">>
<option>Icon Text</option>
<option>Supervisor best practice summary dashboard</option>
</optgroup>
<optgroup label="Unpublished">>
<option>Space Summary</option>
</optgroup>
</select>
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
<div class="form-feedback">
<small class="invalid-feedback">
Example invalid message text
</small>
</div>
</div>
</div>
</div>
</form>
Disabled
Disabled select controls are unable to be edited by users. Any information selected in a disabled select control won’t be submitted when users submit a form.
To disable a select control, add the disabled
attribute to the select
element.
<form>
<div class="form-row">
<div class="form-group col-md-6 mb-3">
<label for="disabledSelectText" class="py-0">Disabled State</label>
<div class="input-group hide-icon">
<select class="form-control custom-select" id="disabledSelectText" disabled>
<option>Highlight</option>
</select>
</div>
</div>
<div class="form-group col-md-6 mb-3">
<label for="disabledSelectIconText" class="py-0">Disabled State</label>
<div class="input-group left-icon">
<select class="form-control custom-select" id="disabledSelectIconText" disabled>
<option>Icon Text</option>
</select>
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
</div>
</form>
Hint text
Hint text provides users with optional guidance on how to fill out a field. To add hint text to your select element, add a <div>
or <small>
element with a .form-text
class to your form
element.
<form>
<div class="form-row">
<div class="form-group col-md-6">
<label for="hintSelectText" class="py-0">Default State</label>
<div class="input-group hide-icon">
<select class="form-control custom-select" id="hintSelectText">
<option>Highlight</option>
<option>Supervisor best practice summary dashboard</option>
<option>Space Summary</option>
</select>
</div>
<div class="form-feedback">
<small class="form-text text-muted d-block">Example hint message text</small>
</div>
</div>
<div class="form-group col-md-6">
<label for="hintSelectIconText" class="py-0">Default State</label>
<div class="input-group left-icon">
<select
class="form-control custom-select"
id="hintSelectIconText">
<optgroup label="Published">
<option>Icon Text</option>
<option>Supervisor best practice summary dashboard</option>
</optgroup>
<optgroup label="Unpublished">
<option>Space Summary</option>
</optgroup>
</select>
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
<div class="form-feedback">
<small class="form-text text-muted d-block">Example hint message text</small>
</div>
</div>
</div>
</form>
Vertical label
Vertical labels appear above the select element.
To add a vertical label to your select element, add the .form-row
class to the form
element.
<form>
<div class="form-row">
<div class="form-group col-md-6 mb-3">
<label for="verticalSelectText" class="py-0">Label</label>
<div class="input-group hide-icon">
<select class="form-control custom-select" id="verticalSelectText">
<option>Highlight</option>
<option>Supervisor best practice summary dashboard</option>
<option>Space Summary</option>
</select>
</div>
</div>
<div class="form-group col-md-6 mb-3">
<label for="verticalSelectIconText" class="py-0">Label</label>
<div class="input-group left-icon">
<select class="form-control custom-select" id="verticalSelectIconText">
<optgroup label="Published">
<option>Icon Text</option>
<option>Supervisor best practice summary dashboard</option>
</optgroup>
<optgroup label="Unpublished">
<option>Space Summary</option>
</optgroup>
</select>
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
</div>
</form>
Horizontal label
Horizontal labels appear inline with the select element, like in the following examples.
To add a horizontal label to your select element, add the .form-inline
and .row
classes to the form
element.
<div class="container">
<form class="form-inline row">
<div class="form-group col-md-12 col-lg-4 mb-3">
<div class="row w-100 mx-0">
<label for="horizontalSelectText" class="pr-2">Label</label>
<div class="input-group hide-icon col-sm-9 col-lg-9 px-0">
<select class="form-control custom-select" id="horizontalSelectText">
<option>Highlight</option>
<option>Supervisor best practice summary dashboard</option>
<option>Space Summary</option>
</select>
</div>
</div>
</div>
<div class="form-group col-md-12 col-lg-4 mb-3">
<div class="row w-100 mx-0">
<label for="horizontalSelectIconText" class="pr-2">Label</label>
<div class="input-group left-icon col-sm-9 col-lg-9 px-0">
<select class="form-control custom-select" id="horizontalSelectIconText">
<optgroup label="Published">
<option>Icon Text</option>
<option>Supervisor best practice summary dashboard</option>
</optgroup>
<optgroup label="Unpublished">
<option>Space Summary</option>
</optgroup>
</select>
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
</div>
</div>
</div>
</form>
</div>
Checkboxes
Checkboxes allow users to select one or more options from a group. Labels and hint text below the list of checkboxes help guide users' decisions.
Use a single checkbox when there’s only one selection to make or choice to confirm. Use multiple checkboxes when one or more options can be selected from a group. Unlike radio buttons, selecting one checkbox won’t clear another checkbox because users can select more than one option.
The following example demonstrates a default checkbox, with no validation applied.
<form>
<div class="form-row">
<div class="col-md-3">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck1" checked="checked">
<label class="custom-control-label" for="customCheck1">Default Checked</label>
<div class="form-feedback">
<small id="exampleCheckboxHint" class="form-text text-muted">Example hint text</small>
</div>
</div>
</div>
<div class="col-md-3">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck2">
<label class="custom-control-label" for="customCheck2">Default Unchecked</label>
</div>
</div>
</div>
</form>
Configuration options
Further configuration can be made to this default input:
For general information on optional form configuration, like adding an icon to your form input control or updating feedback text, see Bootstrap Forms documentation.
For accessibility purposes, icons indicating validation state are included as part of the design system.
Validation examples
Invalid
<form>
<div class="form-row">
<div class="col-md-6">
<div class="custom-control required custom-checkbox">
<input type="checkbox" class="custom-control-input is-invalid" id="customCheck5" required>
<label class="custom-control-label" for="customCheck5"><span>Invalid</span></label>
<div class="form-feedback">
<small id="exampleCheckboxHintInvalid2" class="invalid-feedback">Invalid feedback</small>
<small id="exampleCheckboxHintValid1" class="valid-feedback">Valid feedback</small>
</div>
</div>
</div>
</div>
</form>
Disabled
Add a disabled
boolean attribute to your input
element when another action must be completed before the checkbox is usable.
<form>
<div class="form-row">
<div class="col-md-3">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck3" disabled checked>
<label class="custom-control-label" for="customCheck3">Disabled Checked</label>
</div>
</div>
<div class="col-md-3">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck4" disabled>
<label class="custom-control-label" for="customCheck4">Disabled Unchecked</label>
</div>
</div>
</div>
</form>
Radio buttons
A radio button input allows users to select only one option from a list of choices. Radio buttons are frequently displayed in a radio group. Labels and hint text below radio buttons help guide users' decisions.
The following example demonstrates a default radio button, with no validation applied.
<form>
<div class="form-group radio-group">
<div class="custom-control custom-radio">
<input
type="radio"
id="customRadio1"
name="customRadio"
checked
class="custom-control-input">
<label class="custom-control-label" for="customRadio1">Option A</label>
</div>
<div class="custom-control custom-radio">
<input
type="radio"
id="customRadio2"
name="customRadio"
class="custom-control-input">
<label class="custom-control-label" for="customRadio2">Option B</label>
</div>
<div class="form-feedback">
<small class="form-text text-muted d-block">Example hint message text</small>
</div>
</div>
</form>
Configuration options
Further configuration can be made to this default input:
For general information on optional form configuration, like adding an icon to your form input control or updating feedback text, see Bootstrap Forms documentation.
For accessibility purposes, icons indicating validation state are included as part of the design system.
Validation examples
Invalid
<div class="form-group radio-group is-invalid">
<div class="custom-control custom-radio custom-control-inline">
<input
type="radio"
class="custom-control-input is-invalid"
name="customRadioInline"
checked
id="customInvalidRadio1"
required>
<label class="custom-control-label" for="customInvalidRadio1">Option A</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input
type="radio"
class="custom-control-input is-invalid"
name="customRadioInline"
id="customInvalidRadio2"
required>
<label class="custom-control-label" for="customInvalidRadio2">Option B</label>
</div>
<div class="form-feedback">
<small class="invalid-feedback">There is an error</small>
</div>
</div>
Disabled
Add a disabled
Boolean attribute to your input
element when another action has to be completed before the control is usable.
<form>
<div class="form-group radio-group">
<div class="custom-control custom-radio">
<input
type="radio"
id="customRadio3"
disabled
checked
name="customRadio"
class="custom-control-input">
<label class="custom-control-label" for="customRadio3">Disabled checked</label>
</div>
<div class="custom-control custom-radio">
<input
type="radio"
id="customRadio4"
disabled
name="customRadio"
class="custom-control-input">
<label class="custom-control-label" for="customRadio4">Disabled unchecked</label>
</div>
</div>
</form>
Sample validation forms
Below are sample forms to show validation states.
Custom validation
For custom Bootstrap form validation messages, you’ll need to add the novalidate
Boolean attribute to your <form>
. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript. Try to submit the form below; the JavaScript will intercept the submit button and relay feedback to you. When attempting to submit, you’ll see the :invalid
and :valid
styles applied to your form controls.
Custom feedback styles apply custom colors, borders, focus styles, and background icons to better communicate feedback. Background icons for <select>
s are only available with .custom-select
, and not .form-control
.
If an asterisk is added to a component label, it makes it mandatory. To make a form control mandatory, it’s necessary to add a required Boolean attribute and append a .required
class next to the .form-group
class. The required asterisks only apply on text inputs, text areas and select controls.
<form id="custom-validation-form" class="needs-validation" novalidate>
<div class="form-row">
<div class="form-group col-md-4">
<label for="validationCustom01" class="py-0">First name</label>
<input type="text" class="form-control" id="validationCustom01" value="Mark">
<div class="form-feedback">
<small class="valid-feedback">
Looks good!
</small>
</div>
</div>
<div class="form-group col-md-4">
<label for="validationCustom02" class="py-0">CI</label>
<input type="text" class="form-control" id="validationCustom02" value="34466h">
<div class="form-feedback">
<small class="form-text text-muted">
Identity suggestions
</small>
</div>
</div>
<div class="form-group col-md-4">
<label for="validationCustom03" class="py-0">Passport</label>
<input type="text" class="form-control" id="validationCustom03" value="34466h">
<div class="form-feedback">
<small class="feedback-icon form-text text-muted">Example hint message text</small>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<label for="validationCustom04" class="py-0">Select an option</label>
<select
id="validationCustom04"
class="custom-select">
<optgroup label="Published">
<option>Hypervisor best practices dashboards</option>
<option>Simple dashboard</option>
<option>Another best practice dashboard</option>
</optgroup>
<optgroup label="Unpublished">
<option>Supervisor dashboards 4</option>
<option>Supervisor dashboards 5</option>
</optgroup>
</select>
<div class="form-feedback">
<small class="valid-feedback">
Looks good!
</small>
</div>
</div>
<div class="form-group required col-md-4">
<label for="validationCustom05" class="py-0">Select an option</label>
<select
id="validationCustom05"
class="custom-select"
required>
<option selected disabled value="">Choose...</option>
<option disabled>...</option>
</select>
<div class="form-feedback">
<small id="validationCustomCommentFeedback" class="invalid-feedback">
Please select a valid dashboard
</small>
</div>
</div>
<div class="form-group hide-icon col-md-4">
<label for="validationCustom06" class="py-0">Disabled input</label>
<div class="input-group group-disabled">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
<input
type="text" class="form-control"
id="disabledTextInputIconText"
disabled
autocomplete="off">
</div>
</div>
</div>
<div class="form-row">
<div class="form-group required col-md-6">
<label for="validationCustom07" class="py-0">City</label>
<input type="text" class="form-control" id="validationCustom07" required>
<div class="form-feedback">
<small class="invalid-feedback">
Please provide a valid city
</small>
</div>
</div>
<div class="form-group required col-md-4">
<label for="validationCustom08" class="py-0">Zip</label>
<input type="text" class="form-control" id="validationCustom08" required>
<div class="form-feedback">
<div class="invalid-feedback">
Please provide a valid zip
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group required col">
<label for="validationCustomTextArea" class="py-0">Comments</label>
<textarea id="validationCustomTextArea" class="form-control" aria-describedby="validationCustomCommentFeedback" required></textarea>
<div class="form-feedback">
<small id="validationCustomCommentFeedback" class="invalid-feedback">
Please provide a comment
</small>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="validationCustomTextAreaSuggestions" class="py-0">Suggestions</label>
<textarea id="validationCustomTextAreaSuggestions" class="form-control" aria-describedby="validationCustomSuggestionFeedback"></textarea>
<div class="form-feedback">
<small id="validationCustomSuggestionFeedback" class="form-text text-muted">
Suggestions are welcome
</small>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="validationCustomTextAreaGeneral" class="py-0">General Information</label>
<textarea id="validationCustomTextAreaGeneral" class="form-control" aria-describedby="validationCustomInformationFeedback">General information text.</textarea>
<div class="form-feedback">
<small id="validationCustomInformationFeedback" class="invalid-feedback">
Please provide a comment
</small>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<div class="custom-control custom-checkbox required">
<input type="checkbox" class="custom-control-input" id="clientSideCheck" required>
<label class="custom-control-label" for="clientSideCheck"><span>Agree to the terms</span></label>
<div class="form-feedback">
<small class="invalid-feedback">You must agree</small>
<small class="valid-feedback">Thank you</small>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group radio-group" name="customRadios" id="radioGroupClientValidation">
<div class="custom-control custom-radio">
<input
type="radio"
class="custom-control-input"
name="customRadioClientValidation"
required
id="customRadioClientValidation1">
<label class="custom-control-label" for="customRadioClientValidation1">Option A</label>
</div>
<div class="custom-control custom-radio">
<input
type="radio"
class="custom-control-input"
name="customRadioClientValidation"
required
id="customRadioClientValidation2">
<label class="custom-control-label" for="customRadioClientValidation2">Option B</label>
</div>
<div class="form-feedback">
<div class="invalid-feedback">Please select an option</div>
<div class="valid-feedback">Thank you</div>
</div>
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
var agreeCheck = document.getElementById('clientSideCheck');
var radioGroup = document.getElementById('radioGroupClientValidation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
// set invalid inputs
agreeCheck.classList.add('is-invalid');
radioGroup.classList.add('is-invalid');
var customSelect2 = document.getElementById('validationCustom05');
customSelect2.classList.add('is-invalid');
var cityInput = document.getElementById('validationCustom07');
cityInput.classList.add('is-invalid');
var zipInput = document.getElementById('validationCustom08');
zipInput.classList.add('is-invalid');
var commentsTextArea = document.getElementById('validationCustomTextArea');
commentsTextArea.classList.add('is-invalid');
// set valid inputs
var firstNameInput = document.getElementById('validationCustom01');
firstNameInput.classList.add('is-valid');
var customSelect = document.getElementById('validationCustom04');
customSelect.classList.add('is-valid');
}
form.classList.add('was-validated');
}, false);
});
var form = document.getElementById('custom-validation-form');
agreeCheck.addEventListener('click', function(event){
if(agreeCheck.checked){
agreeCheck.classList.remove('is-invalid');
if(form.classList.contains('was-validated')){
agreeCheck.classList.add('is-valid');
}
}else{
agreeCheck.classList.remove('is-valid');
if(form.classList.contains('was-validated')){
agreeCheck.classList.add('is-invalid');
}
}
})
const radios = document.getElementsByName('customRadioClientValidation');
for (var i = 0; i < radios.length; i++) {
radios[i].addEventListener('change', function(event){
event.preventDefault();
radioGroup.classList.remove('is-invalid')
for (var i = 0; i < radios.length; i++) {
if(radios[i].checked){
if(form.classList.contains('was-validated')){
radioGroup.classList.add('is-valid')
radios[i].classList.add('is-valid')
}
}else{
radios[i].classList.remove('is-valid')
radios[i].classList.remove('is-invalid')
}
}
});
}
}, false);
})();
</script>
Server side validation
You can indicate invalid form fields with the .is-invalid
class. Note that .invalid-feedback
is also supported with this class.
For invalid fields, ensure that the invalid feedback/error message is associated with the relevant form field using aria-describedby
. This attribute allows more than one id
to be referenced, in case the field already points to additional form text.
<form>
<div class="form-row">
<div class="form-group hide-icon col-md-6">
<label for="validationServer01" class="py-0">First name</label>
<div class="input-group">
<span class="prepend-placeholder"></span>
<input
id="validationServer01"
type="text" class="form-control is-valid"
value="Mark"
autocomplete="off">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="feedback-icon fa fas fa-user"></i>
</span>
</div>
<div class="form-feedback">
<small class="valid-feedback">
Looks good!
</small>
</div>
</div>
</div>
<div class="form-group col-md-6">
<label for="validationServer02" class="py-0">CI</label>
<div class="input-group">
<input type="text" class="form-control" id="validationServer02" value="43657g">
<div class="form-feedback">
<small class="form-text text-muted">
Identity suggestions
</small>
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group required col-md-6">
<label for="validationServer03" class="py-0">City</label>
<input type="text" class="form-control is-invalid" id="validationServer03" aria-describedby="validationServer03Feedback" required>
<div class="form-feedback">
<small id="validationServer03Feedback" class="invalid-feedback">
Please provide a valid city
</small>
</div>
</div>
<div class="form-group required col-md-4">
<label for="validationServer04" class="py-0">Zip</label>
<input type="text" class="form-control is-invalid" id="validationServer04" aria-describedby="validationServer05Feedback" required>
<div class="form-feedback">
<small id="validationServer05Feedback" class="invalid-feedback">
Please provide a valid zip
</small>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="validationServer05" class="py-0">Select an option</label>
<div class="input-group">
<select
class="form-control custom-select is-valid"
id="validationServer05">
<optgroup label="Published">
<option>Hypervisor best practices dashboards</option>
<option>Simple dashboard</option>
<option>Another best practice dashboard</option>
</optgroup>
<optgroup label="Unpublished">
<option>Supervisor dashboards 4</option>
<option>Supervisor dashboards 5</option>
</optgroup>
</select>
<div class="form-feedback">
<small class="valid-feedback">
Looks good!
</small>
</div>
</div>
</div>
<div class="form-group required col-md-6">
<label for="validationServer06" class="py-0">Select an option</label>
<div class="input-group">
<select
class="form-control custom-select is-invalid"
id="validationServer06"
required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div class="form-feedback">
<small id="validationCustomCommentFeedback" class="invalid-feedback">
Please select a valid dashboard
</small>
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group required col">
<label for="validationServerTextArea" class="py-0">Comments</label>
<textarea id="validationServerTextArea" class="form-control is-invalid" aria-describedby="validationServerCommentFeedback" required></textarea>
<div class="form-feedback">
<small id="validationServerCommentFeedback" class="invalid-feedback">
Please provide a comment
</small>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="validationServerTextAreaSuggestions" class="py-0">Suggestions</label>
<textarea id="validationServerTextAreaSuggestions" class="form-control " aria-describedby="validationServerSuggestionFeedback"></textarea>
<div class="form-feedback">
<small id="validationServerSuggestionFeedback" class="form-text text-muted">
Suggestions are welcome
</small>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="validationServerTextAreaGeneral" class="py-0">General Information</label>
<textarea id="validationServerTextAreaGeneral" class="form-control is-valid" aria-describedby="validationServerInformationFeedback">General information text.</textarea>
<div class="form-feedback">
<small id="validationServerInformationFeedback" class="valid-feedback">
Please provide a comment
</small>
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6">
<div class="custom-control custom-checkbox required">
<input type="checkbox" class="custom-control-input is-invalid" id="serverSideCheck" required>
<label class="custom-control-label" for="serverSideCheck" onclick="validateTerms()"><span>Agree to the terms</span></label>
<div class="form-feedback">
<small class="invalid-feedback hide-feedback-icon">You must agree (icon hidden example)</small>
<small class="valid-feedback">Thank you</small>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group radio-group is-invalid" id="radioGroupInlineValidation">
<div class="custom-control custom-radio custom-control-inline">
<input
type="radio"
class="custom-control-input is-invalid"
name="customRadioServerValidation"
id="customRadioValidationInline1"
required>
<label class="custom-control-label" for="customRadioValidationInline1">Option A</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input
type="radio"
class="custom-control-input is-invalid"
name="customRadioServerValidation"
id="customRadioValidationInline2"
required>
<label class="custom-control-label" for="customRadioValidationInline2">Option B</label>
</div>
<div class="form-feedback">
<small class="invalid-feedback">There is an error</small>
<small class="valid-feedback">Thank you</small>
</div>
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
function validateTerms() {
var checkAgree = document.getElementById("serverSideCheck");
if(checkAgree.checked){
checkAgree.className = "custom-control-input is-invalid";
}else{
checkAgree.className = "custom-control-input is-valid";
}
};
(function(){
const radioGroup = document.getElementById('radioGroupInlineValidation');
const radios = document.getElementsByName('customRadioServerValidation');
for (var i = 0; i < radios.length; i++) {
radios[i].addEventListener('change', function(event){
event.preventDefault();
radioGroup.classList.remove('is-invalid')
radioGroup.classList.add('is-valid')
for (var i = 0; i < radios.length; i++) {
if(radios[i].checked){
radios[i].classList.remove('is-invalid')
radios[i].classList.add('is-valid')
}else{
radios[i].classList.remove('is-invalid')
radios[i].classList.remove('is-valid')
}
}
});
}
})()
</script>