Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

In the following example:

(function (angular) {
  var module = angular.module('test', []);
  
  module.controller('TestCtrl', ['$scope', function ($scope) {
    $scope.before = $scope.after = true;
    $scope.profile = [
      { key: 'Prop1', type: 'text', value: 'test' },
      { key: 'Prop2', type: 'number', value: 42 },
      { key: 'Prop3', type: 'complex', value: 15, extra: 1 },
    ];
  }]);
  
})(angular);
        
angular.element(document).ready(function () {
  angular.bootstrap(document, ['test']);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">

<form data-ng-controller="TestCtrl">
  <div class="form-group">
    <label class="control-label">
      <input type="checkbox" data-ng-model="before" />
      Show "before"
    </label>
  </div>
  <div class="form-group">
    <label class="control-label">
      <input type="checkbox" data-ng-model="after" />
      Show "after"
    </label>
  </div>
  <div class="form-group" data-ng-repeat="prop in profile">
    <label class="control-label">{{prop.key}}</label>
    <div class="input-group" data-ng-switch="prop.type">
      <span class="input-group-addon" data-ng-if="before">before</span>
      <input data-ng-switch-when="text" class="form-control"
             type="text" data-ng-model="prop.value" />
      <input data-ng-switch-when="number" class="form-control"
             type="number" data-ng-model="prop.value" />
      <span data-ng-switch-when="complex">
        <input class="form-control" type="number" data-ng-model="prop.value"
               style="display:inline-block;width:calc(100% - 90px)" />
        <select class="form-control" data-ng-model="prop.extra"
                style="display:inline-block;width:90px">
          <option value="1">one</option>
          <option value="2">two</option>
        </select>
      </span>
      <span class="input-group-addon" data-ng-if="after">after</span>
    </div>
  </div>
</form>

I'm using ngSwitch to display different content for the various properties based on their model data. This much is working great.

The first two properties (which just use a simple input control), integrate nicely with the Bootstrap input-group and get either rounded or flat corners as appropriate whether the before/after parts are shown or not.

The third property (which uses two controls in a containing span), doesn't -- its controls always have rounded corners even when the before/after parts are shown and they shouldn't.

I know that this is because of the way that the input-group's CSS tweaks its children -- it will be trying to change the border of the span instead of the internal elements. Although it might be doing something to the internal controls, as they do seem to have non-rounded corners in the middle where they join (which is good).

Is there a way to fix this generically? What's the best way to correct this? (Note that in my real code the contents of the span are generated by a directive, so I can consider JS-based solutions, although pure CSS may be preferable.)


Alternately, if the AngularJS is confusing, an even more simplified example that shows the same basic issue:

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

<form>
  <div class="form-group">
    <label class="control-label">Prop</label>
    <div class="input-group">
      <span class="input-group-addon">before</span>
      <span>
        <input class="form-control" type="number" value="42"
               style="display:inline-block;width:calc(100% - 90px)" />
        <select class="form-control"
                style="display:inline-block;width:90px">
          <option value="1" selected>one</option>
          <option value="2">two</option>
        </select>
      </span>
      <span class="input-group-addon">after</span>
    </div>
  </div>
</form>

Removing the span tag around the input/select fixes the problem, but unfortunately that's not a valid solution (due to the AngularJS).

share|improve this question

1 Answer 1

I'd been puzzling over this for days, but in a mysterious case of "writing the problem down provides the answer", I think I've found it after all.

Adding the following CSS seems to do the trick:

.input-group span:not(:first-child) .form-control:first-child {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

.input-group span:not(:last-child) .form-control:last-child {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

(function (angular) {
  var module = angular.module('test', []);
  
  module.controller('TestCtrl', ['$scope', function ($scope) {
    $scope.before = $scope.after = true;
    $scope.profile = [
      { key: 'Prop1', type: 'text', value: 'test' },
      { key: 'Prop2', type: 'number', value: 42 },
      { key: 'Prop3', type: 'complex', value: 15, extra: 1 },
    ];
  }]);
  
})(angular);
        
angular.element(document).ready(function () {
  angular.bootstrap(document, ['test']);
});
.input-group span:not(:first-child) .form-control:first-child {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

.input-group span:not(:last-child) .form-control:last-child {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">

<form data-ng-controller="TestCtrl">
  <div class="form-group">
    <label class="control-label">
      <input type="checkbox" data-ng-model="before" />
      Show "before"
    </label>
  </div>
  <div class="form-group">
    <label class="control-label">
      <input type="checkbox" data-ng-model="after" />
      Show "after"
    </label>
  </div>
  <div class="form-group" data-ng-repeat="prop in profile">
    <label class="control-label">{{prop.key}}</label>
    <div class="input-group" data-ng-switch="prop.type">
      <span class="input-group-addon" data-ng-if="before">before</span>
      <input data-ng-switch-when="text" class="form-control"
             type="text" data-ng-model="prop.value" />
      <input data-ng-switch-when="number" class="form-control"
             type="number" data-ng-model="prop.value" />
      <span data-ng-switch-when="complex">
        <input class="form-control" type="number" data-ng-model="prop.value"
               style="display:inline-block;width:calc(100% - 90px)" />
        <select class="form-control" data-ng-model="prop.extra"
                style="display:inline-block;width:90px">
          <option value="1">one</option>
          <option value="2">two</option>
        </select>
      </span>
      <span class="input-group-addon" data-ng-if="after">after</span>
    </div>
  </div>
</form>

(Leaving this question here in case someone else has a similar problem, or a better solution.)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.