2

I am trying to do something that in my head is very simple, but all my attempts to make it happen have failed.

Using ng-model and $setValidity(), I can make any field valid or invalid and angular will add the 'ng-invalid' class to any invalid fields, which is great. I'm using bootstrap, which has built-in styles for 'input:invalid', which adds a red border around all invalid elements when those elements are in focus.

My problem is that I would like to add a *** after every input in my form that is invalid so that the user can quickly see which fields need to be fixed. I thought I could do that using only CSS by doing the following:

input.ng-invalid{
    border: 2px solid red; 
}
input.ng-invalid:after{
    content: '***';
}

I have an plunker that demonstrates a simple example of this here. The example <input> is required, so if you just remove the text from the field, it immediately becomes invalid and gets a big red border. But it doesn't get the content: '***'; style.

Do I just not understand how the :after selector works in CSS? Or am I doing something else wrong? Any pointers would be greatly appreciated. Thanks!

tennisgent
  • 14,165
  • 9
  • 50
  • 48

1 Answers1

7

Removing input in your selector worked for me in your plunker.

CSS2

.ng-invalid:after {
  content: '***';
}

CSS3

.ng-invalid::after {
  content: '***';
}

It does not seem to work on an input. It is adding the *** after the form which also has the ng-invalid class. See this other answer: https://stackoverflow.com/a/4660434/1036025

EDIT 1

You could do something like this, but it requires a container tag beside your input:

html

<input type="text" placeholder="This field is required" ng-model="myVal" required="" class="my-input" />
<span></span>

css

input.ng-invalid + span::after {
  content: '***';
}

EDIT 2

You could also add dynamically the span with a directive, either on the input element:

app.directive('input', function() {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {
      elem.after("<span></span>");
    }
  }
});

Or on the required attribute (I suggest to use ng-required):

app.directive('required', function() {
  return {
    restrict: 'A',
    link: function(scope, elem, attrs) {
      elem.after("<span></span>");
    }
  }
});

Doing it that way, in combination with the css rule, you would not have to change anything from your view's html.

Community
  • 1
  • 1
jpmorin
  • 6,008
  • 2
  • 28
  • 39