How to get contents of invalid form model in AngularJS?
Asked Answered
O

1

5

I have an AngularJS web app that has a form containing a textarea as follows:

<textarea required ng-maxlength="1000" ng-model="foo"></textarea>

The validation logic simply says that the user must enter a value up to a maximum of 1000 characters. Suppose further that I decide that I want the app to show the user how many characters remain before the limit is reached. No problem: I simply write this:

<div ng-if="foo.length <= 1000">
    {{ 1000 - foo.length }} characters remaining
</div>

The above works perfectly. Now, suppose that I want to display a message indicating that the user has typed too many characters, so I write the following:

<div ng-if="foo.length > 1000">
    {{ foo.length - 1000 }} characters too many
</div>

The above code does not work and it appears that such is the case because the input value is not accepted by Angular, so foo is left undefined, and I can't tell the user how many characters must be removed for the input to be valid.

Therefore, I would like to know if there is a way to get the value of an invalid input and tell the user a meaningful reason that it is invalid.

Oppugn answered 20/10, 2015 at 16:22 Comment(0)
E
7

You can use the $viewValue of the NgModelController https://code.angularjs.org/1.3.10/docs/api/ng/type/ngModel.NgModelController

To access it, you would need to add a name to both the form and the input.

<form name="someForm">
  ...
  <textarea required ng-maxlength="1000" ng-model="foo" name="lotsaText"></textarea>
  ...
  <div ng-if="someForm.lotsaText.$viewValue.length > 1000">
    {{ someForm.lotsaText.$viewValue.length - 1000 }} characters too many
  </div>
</form>

See the sample code snippet below to see how it works where I also incorporated kappaismyname's suggestions

(function(){
  "use strict";
  
  var app = angular.module('fooApp', []);
  
  app.controller('MainCtrl', function($scope) {
    $scope.model = {foo:"Default text here"};
  });
  
})();
textarea.ng-invalid {
  border: 2px solid red;
}
.validation-message {
  color: red;
}
<!DOCTYPE html>
<html ng-app="fooApp">

  <head>
    <meta charset="utf-8" />
    <script src="https://code.angularjs.org/1.3.17/angular.js" ></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>model.foo: {{model.foo | json}}</p>
    <form name="someForm">
      Enter text, but  not too much:<br>
      <textarea required ng-maxlength="25" ng-model="model.foo" name="lotsaText"></textarea>
    
      <div ng-if="someForm.lotsaText.$error.maxlength" class="validation-message">
        {{ someForm.lotsaText.$viewValue.length - 25 }} characters too many
      </div>
      <div ng-if="someForm.lotsaText.$error.required" class="validation-message">
        A non-empty value is required
      </div>
    </form>
  </body>

</html>
Esterify answered 20/10, 2015 at 16:49 Comment(2)
upvoted! or someForm.lotsaText.$error.maxlength inside of ng-if so you don't have to check the length.Rackety
also, angular will add ng-invalid class to the textarea if there are more chars then 1000.Rackety

© 2022 - 2024 — McMap. All rights reserved.