2
votes

Using Bootstrap 3 forms. In a normal Bootstrap form with field labels on top on input fields (no form-inline, no form-horizontal) I want to be able to display a flexible number of controls in the same row. For example:

  • 4 controls on a full width screen
  • 2 controls on a medium size screen
  • 1 control on small screens

To get this we can use a Bootstrap row to group all four controls and appropiate col-xx-x classes for each control. See code below.

The problem with this layout is that when the controls are displayed stacked (more than one row) and the help-block used to display errors in controls is displayed the layout of the control just below the help text is pushed one position to the right. The reason for this is that those controls share the same row and the extra height added by the help message fills one space in the lower row. See the example provided.

<html>

<head>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />
</head>

<body>
  <div class="container">
    <form>
      <div class="row">
        <div class="form-group col-xs-6 col-md-4 col-lg-3">
          <label for="exampleInputEmail1">Email address</label>
          <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
          <span id="errorMessage" class="help-block" style="display: none">This is the error message</span>
        </div>
        <div class="form-group col-xs-6 col-md-4 col-lg-3">
          <label for="exampleInputPassword1">Password</label>
          <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
        </div>
        <div class="form-group col-xs-6 col-md-4 col-lg-3">
          <label for="other">Other</label>
          <input type="text" class="form-control" id="exampleInputPassword1" placeholder="Other">
        </div>
      </div>
    </form>
    <button class="btn btn-default" onclick="function showError() {document.getElementById('errorMessage').style.display = 'inline'};showError();">
    Show error message in email control
  </button>
  </div>
</body>

</html>

I have experimented with form-inline forms, but then the help text is displayed on the right side of the control instead of below.

2

2 Answers

2
votes

I hope this is what you are looking for...

.no-padding {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

.no-right-margin {
  margin-right: 0 !important;
}
<html>

<head>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />
</head>

<body>
  <div class="container">
    <form>
      <div class="row">
        <div class="form-group col-xs-6 col-md-4 col-lg-3">
          <label for="exampleInputEmail1">Email address</label>
          <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
          <span id="errorMessage" class="help-text" style="display: none">This is the error message</span>
        </div>
        <div class="form-group col-xs-6 col-md-4 col-lg-3">
          <label for="exampleInputPassword1">Password</label>
          <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
        </div>
      </div>
      <div class="col-xs-6 col-md-4 col-lg-3 no-padding">
        <div class="row no-right-margin">
          <div class="form-group col-xs-12 col-md-12 col-lg-12">
            <label for="other">Other</label>
            <input type="text" class="form-control" id="exampleInputPassword1" placeholder="Other">
          </div>
        </div>
      </div>
    </form>
    <button class="btn btn-default" onclick="function showError() {document.getElementById('errorMessage').style.display = 'inline'};showError();">
    Show error message in email control
  </button>
  </div>
</body>

</html>
1
votes

I ran into this same issue and went with the absolute positioning you hinted at. Here is my bootstrap override

.form-group {
  position: relative;
  .help-block { position: absolute; right: 2rem; bottom: -3rem }
}

I put it the right so when the field are stacked it doesn't clutter with the label. I haven't determined the full consequences of this in all contexts but for the issue at hand it seems to work well. Future pages may make me tweak the values for one reason or another.