Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

I am very new to angularjs and I just cant figure out how I would go about validating my inputs.

I have an input which should never be empty. The model will always have a value. Whenever a user inputs invalid data (i.e nothing or maybe invalid characters) I would like the input to revert to its original value.

For instance, If the initial value was 50 and I deleted all of that (or entered text) and deselected the input, I would expect the input's value to change back to 50.

Here is my controller:

var MyController = null;
app.controller("MyController", ["$scope", function($scope) {
    $scope.data = myData;
    $scope.validate = function(value, oldValue) {
        if(!value || value == "") {
            // Do something after validation
            value = oldValue;
        }
        // Our value should be valid now (either replaced or changed)
    }
    MyController = $scope;
}]);

And my HTML (i would rather not have to type data.something twice if possible):

<input type="text" ng-model="data.something" ng-change="validate()" />

Small Clarification: If the value of the input is "50" and a user removes the "0", the input would be at "5" which is valid. However if the user adds a "x" after I DONT want the input to change, it should still be at "5". However if all the input is empty, I would like onBlur for the original value to be placed back into the input and the model unchanged.

share|improve this question
    
There is (at least) one tricky detail: say "50" is valid, as well as "5", but "5x" isn't (e.g. a numeric input). The user focuses the input while it contains "50", deletes the trailing zero (now it contains "5" - still valid) and then appends "x" and focuses out. Noe the input contains "5x" - invalid. What value should the input revert to? – Nikos Paraskevopoulos 14 hours ago
    
@NikosParaskevopoulos Look at my updated Answer with a clarification, sorry for the confusion again. – Hunter Mitchell 14 hours ago
    
Why not HTML5? <input type="text" ng-model="data.something" ng-change="validate()" required="required" /> – Baruch 14 hours ago
    
@Baruch This is not a form. To my knowledge that is only checked when the form is submitted. – Hunter Mitchell 14 hours ago
1  
Some alternatives that may be helpful: the built-in forms stuff supports validation incl the new html5 input types and attributes, and additionally ng-pattern may also be helpful. – Jeroen 14 hours ago
up vote 2 down vote accepted

Yep, you need ng-blur and probably ng-focus:

<input type="text" ng-model="data.something" ng-focus="store()" ng-blur="revertIfInvalid()"/>

$scope.store = function() {
  $scope.stored = $scope.data.something;
}

$scope.revertIfInvalid= function() {
  if (!$scope.data.something) {
    $scope.data.something = $scope.stored;
  }
}

This will work, but to make it reusable, you then want to make directive for this, like:

app.directive('fancydirective', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(sc, elem, attrs, ngModelCtrl) {
      var stored;
      elem.on('focus', function() {
        sc.$apply(function() {
          stored = ngModelCtrl.$modelValue;
        });
      });
      elem.on('blur', function() {
        sc.$apply(function() {
          if (ngModelCtrl.$invalid) {
            ngModelCtrl.$setViewValue(stored);
            ngModelCtrl.$render();
          }
        });
      });
    }
  }
});

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

share|improve this answer
    
This works perfectly, however is there a way I can add further validation (like allowing only text)? So, if I was to press "0" in this case, nothing would happen and the model data wouldn't change. – Hunter Mitchell 14 hours ago
    
@HunterMitchell You can add validation logic inside the elem.on('blur', ...). Maybe add an if statement that tests a regex that returns false if there's any character that's not a word character. – Baruch 14 hours ago
    
@Baruch that makes sense. Could I also do validation within elem.on('change', ...) to validate even further (i.e. remove any numbers as they are typed) – Hunter Mitchell 14 hours ago
    
@Hunter, as u see in this directive there is a check for valid - so you can add any other validator like ng-pattern or custom. – Petr Averyanov 8 hours ago

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.