Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS update model only on blur

Tags:

angularjs

I have a requirement that the model should only be updated when the input is blurred or enter is pressed and error/success message will only be shown after so and not during input. Previously I was using AngularJS 1.2 rc2 and have the following code:

Javascript:

angular.module('app', []).directive('ngModelOnblur', function () {
  return {
      restrict: 'A',
      require: 'ngModel',
      link: function (scope, element, attrs, ngModelCtrl) {
          if (attrs.type === 'radio' || attrs.type === 'checkbox') { return; }
          var update = function () {
              scope.$apply(function () {
                  ngModelCtrl.$setViewValue(element.val().trim());
                  ngModelCtrl.$render();
              });
          };
          element.off('input').off('keydown').off('change').on('focus', function () {
              scope.$apply(function () {
                  ngModelCtrl.$setPristine();
              });
          }).on('blur', update).on('keydown', function (e) {
              if (e.keyCode === 13) {
                  update();
              }
          });
      }
  };
})
.controller('Ctrl', ['$scope', function ($scope) {
  $scope.getClass = function (input) {
    if (input.$pristine) { return ''; }
    return input.$invalid ? 'has-error' : 'has-success';
  };
}]);

HTML:

<div ng-controller="Ctrl">
  <form name="form" novalidate>
    <div ng-class="getClass(form.firstname)">
      <input type="text" name="firstname" ng-model="firstname" ng-model-onblur ng-pattern="/^\d{4}$/" />
      <div class="error">error</div>
      <div class="success">success</div>
      $pristine: {{form.firstname.$pristine}}
    </div>
  </form>
</div>

CSS:

  .error, .success {
    display: none; 
  }
  .has-error .error, .has-success .success {
    display: block; 
  }

But since I upgraded to RC3, things start to break. Although I removed the event handler for input, change, and keydown, $pristine is still set to false during input and so the message will be shown.

I tried setting terminal: true, priority: -1 for the directive, but it still doesn't work. What am i doing wrong?

Here is the plunker: http://plnkr.co/edit/8FliNc?p=preview

Thanks in advance

like image 955
Lucius Avatar asked Sep 25 '26 06:09

Lucius


2 Answers

It works for me if you give your directive priority: 1. Setting terminal = true means ng-model is never called, priority -1 is not supported I think.

http://plnkr.co/edit/mZyWw8?p=preview

Just some minor things I found with the directive: when you re-focus the input, the model is resetted (form set to pristine), evne if the model is valid. If you empty the input, after the model has been set, the model is not set to undefined.

like image 60
Narretz Avatar answered Sep 28 '26 00:09

Narretz


I think this is now natively supported within Angular JS.

See: https://docs.angularjs.org/api/ng/directive/ngModelOptions

I'm using angular 1.6 and the "updateOn: 'blur'" seems to work for me.

like image 35
JohnB Avatar answered Sep 27 '26 23:09

JohnB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!