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.

The validation label below the field should be as informative as possible when describing the approval of the user’s data.

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:

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 text
  • small.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.

Horizontal labels may require adjusting margins and padding.
<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:

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:

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>