AngularJS Form Validation: $valid Always True

Issue

I’m having trouble with AngularJS form validation. Below is a simple two-field form with the only requirements being that data for each field is required, one of which is of “email” type.

The trouble is, no matter what I put as the value for either of the two fields, Angular’s .$valid always returns the value of true and $invalid returns the value of false. It can be an empty field, a valid/invalid email address, or as long a string as I choose. The result is the same.

Therefore, the submit button is never disabled because I’m using

ng-disabled="FormLogin.$invalid"

However, if I use a variable from the controller, the submit button is disabled

ng-disabled="disableSubmit" 

This suggests that Angular is working, but I haven’t set up the directives correctly in the form controls. Note that ng-model directives appear to applied correctly.

I’ve tried many different variations of code on them, some pretty desperate, to no avail. There are other SO questions regarding this same subject, but I didn’t find any that applied. Any suggestions you may have would be great. Thanks.

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
  </head>
<body>
<div ng-app="myApp" ng-controller="formCtrl" align="center" style="width:400px;padding: 10px 10px 10px 10px;">
<table class="table table-stripe"><form name="FormLogin" ng-submit="submitForm(FormLogin.$valid)" novalidate>
  <tr>
    <td>User:</td>
    <td>
    <input type="email" name="email" class="form-control" ng-model="email" required />
    </td>
  </tr>
  <tr>
    <td>Pwd:</td>
    <td><input type="password" name="password" class="form-control" ng-model="password" required /></td>
  </tr>
  <tr>
    <td colspan="2" align="center">
    <button type="submit" class="form-control" style="width:200px;" ng-disabled="FormLogin.$invalid">Log In</button>
    </td>
  </tr></form>
</table>
</div>
<script>
var app = angular.module('myApp', []);

app.controller('formCtrl', function($scope) {
    $scope.disableSubmit = true;
    $scope.email = 'testUser@testDomain.com';
    $scope.password = 'y!keZ';
    $scope.submitForm = function(isValid) {
    alert($scope.email + ':' + $scope.password + ':' + isValid);
    };
  });

</script>
</body>
</html>

Solution

Your issue is due to invalid html, you have nested the form directly under table which is incorrect and the browser will throw it out of the table (or whatever it decides to do) as it renders (before even angular processes the DOM) and the angular validations does not work properly.

Demo wrapping the table inside the form

var app = angular.module('myApp', []);

app.controller('formCtrl', function($scope) {
  $scope.disableSubmit = true;
  $scope.email = 'testUser@testDomain.com';
  $scope.password = 'y!keZ';
  $scope.submitForm = function(isValid) {
    console.log($scope.email + ':' + $scope.password + ':' + isValid);
  };
});
<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>

<body>
  <div ng-app="myApp" ng-controller="formCtrl" align="center" style="width:400px;padding: 10px 10px 10px 10px;">

    <form name="FormLogin" ng-submit="submitForm(FormLogin.$valid)" novalidate>
      <table class="table table-stripe">

        <tr>
          <td>User:</td>
          <td>
            <input type="email" name="email" class="form-control" ng-model="email" required />
          </td>
        </tr>
        <tr>
          <td>Pwd:</td>
          <td>
            <input type="password" name="password" class="form-control" ng-model="password" required />
          </td>
        </tr>
        <tr>
          <td colspan="2" align="center">
            <button type="submit" class="form-control" style="width:200px;" ng-disabled="FormLogin.$invalid">Log In</button>
          </td>
        </tr>

      </table>
    </form>
  </div>

</body>

</html>

Answered By – PSL

Answer Checked By – Jay B. (AngularFixing Admin)

Leave a Reply

Your email address will not be published.