Skip to main content

Forms

Form controls, layout and validation that work with Angular forms.

Bootstrap’s forms docs describe the markup and CSS.

Example

Put each control in a bsFormField with a bsFormLabel. The field gives the control an id, points the label to it and sets aria-describedby to its help text, so you don’t write ids yourself. Bind controls with Reactive Forms, ngModel or Signal Forms as usual.

We’ll never share your email with anyone else.
<form class="vstack gap-3" [formGroup]="form" (ngSubmit)="save()">
  <div bsFormField>
    <label bsFormLabel>Email address</label>
    <input type="email" bsFormControl formControlName="email" autocomplete="email" />
    <div bsFormText>We’ll never share your email with anyone else.</div>
  </div>
  <div bsFormField>
    <label bsFormLabel>Password</label>
    <input
      type="password"
      bsFormControl
      formControlName="password"
      autocomplete="current-password" />
  </div>
  <div bsFormField>
    <input type="checkbox" bsCheck formControlName="remember" />
    <label bsLabel>Check me out</label>
  </div>
  <button type="submit" bsButton theme="primary" class="align-self-start">Submit</button>
</form>
@if (submitted()) {
  <p class="mt-3 mb-0" role="status">
    Submitted: <code>{{ submitted() }}</code>
  </p>
}

Signal Forms

Controls also follow Signal Forms bound with [formField]. Once a control is touched, or submit() marks every field as touched, invalid controls get .is-invalid, aria-invalid and their feedback message.

Please enter your name.
Please enter a valid email address.
<form class="vstack gap-3" novalidate (submit)="save($event)">
  <div bsFormField>
    <label bsFormLabel>Name</label>
    <input bsFormControl [formField]="signup.name" autocomplete="name" />
    <div bsInvalidFeedback>Please enter your name.</div>
  </div>
  <div bsFormField>
    <label bsFormLabel>Email address</label>
    <input type="email" bsFormControl [formField]="signup.email" autocomplete="email" />
    <div bsInvalidFeedback>Please enter a valid email address.</div>
  </div>
  <button type="submit" bsButton theme="primary" class="align-self-start">Sign up</button>
  @if (saved()) {
    <p class="mb-0" role="status">Thanks for signing up!</p>
  }
</form>

Disabled forms

Add disabled to a <fieldset> to disable every control inside it. With Reactive Forms, call disable() on the form group instead, because Angular sets the disabled property of each control.

Disabled fieldset example
HTML
<form>
  <fieldset disabled class="vstack gap-3">
    <legend>Disabled fieldset example</legend>
    <div bsFormField>
      <label bsFormLabel>Disabled input</label>
      <input bsFormControl placeholder="Disabled input" />
    </div>
    <div bsFormField>
      <label bsFormLabel>Disabled select menu</label>
      <select bsFormControl>
        <option>Disabled select</option>
      </select>
    </div>
    <div bsFormField>
      <input type="checkbox" bsCheck />
      <label bsLabel>Can’t check this</label>
    </div>
    <button type="submit" bsButton theme="primary" class="align-self-start">Submit</button>
  </fieldset>
</form>