1

In Angular, I am trying to validate a value of a field on blur. I have a list of customers, and I want to check if the model value in the field is in my list of customers. If not, I want to set the validity to false.

I know that ng-model-options="{updateOn: 'blur'} exists, however, I can't use this because the field is a typeahead so it must update based on the model. The validation is what needs to happen on blur.

The answer seems to be:

  1. Write it as a function in the controller and use $setValidity just as you would in a directive. Use ng-blur to trigger the function in the input field.

    -However, I keep running into examples where a custom validation (make the field invalid if the model value does not match one in the list) is only written as a directive. Are there examples of custom validation written as a function?

  2. Write a directive that only triggers on blur.

However, I can't find examples that do either of these things. Does anybody have an example of custom validation as a function OR a directive that only updates on blur of the field?

I found this link very helpful for custom validation but I still have the same problem with the difference between a function and a directive: How to add custom validation to an AngularJS form?

Community
  • 1
  • 1
jenryb
  • 2,017
  • 12
  • 35
  • 72

2 Answers2

3

As something we've been working on recently:

<form name='vm.formName' id='vm.formName' novalidate>
  <input type='text' id='textField' name='textField' ng-blur='vm.blurMethod()' ng-model='vm.model.text' />
  // The submit is only here for show;
  <input type='submit' id='submit' ng-click='vm.submitForm()' />
</form>

In the controller:

blurMethod() {
  if (this.formName.textField.$viewValue !== myArbitraryValue) {
    // $setValidity called on the form, setting the textfield's validity to false
    // then you can have your own validators show the error in the template
    this.formName.$setValidity('textField', false);
  }
}

That's off the top of my head, will take a look in the morning to see if it mirrors what we've been using. Updated the $setValidity call now.

This assumes you're using the controllerAs: 'vm' syntax, which is why the form has a name 'vm.formname' and the controller is using 'this'.

rrd
  • 5,789
  • 3
  • 28
  • 36
  • this looks promising, looking forward to the update tomorrow – jenryb May 31 '16 at 21:20
  • Hey rrd, any luck finding if it matches what you've been using? – jenryb Jun 01 '16 at 16:15
  • Yeah I updated the post, it's what we were using. the $setValidity() is called on the form and takes the input field as the argument. – rrd Jun 01 '16 at 16:16
  • Accepted your answer, had to tweak for my solution but you led me to the right place. Only annoying thing is that apparently selecting on a typeahead counts as a "blur" action so it runs through the function twice. – jenryb Jun 01 '16 at 16:55
1

I have used ui-bootstrap for typeahead with plenty of control on your validation ui-bootstrap typeahead

EDIT- Code sample

<input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control" typeahead-no-results="$scope.matchFail"> <div ng-show="$scope.matchFail">Not on list!!</div>

When you choose a value that is not on the list, the div is displayed

Mike
  • 1,645
  • 3
  • 13
  • 21
  • The typeahead works fine. What kind of validation are you talking about? I want there to be an error in my form if there are no results: "typeahead-no-results $ (Default: angular.noop) - Binding to a variable that indicates if no matching results were found." Right now it shows that there are no results but it does not throw an error in my form. – jenryb May 31 '16 at 20:34
  • This is not helpful to me. I have the no-results working, it displays the div. That part is simple. What does not work is validation, for example, what is shown in this link: http://stackoverflow.com/questions/12581439/how-to-add-custom-validation-to-an-angularjs-form . In this case, the form should not be able to be submitted if typeahead-no-results shows up. If it helps, the answer below is closer to answering what I am looking for. – jenryb May 31 '16 at 21:54