roloenusa
roloenusa

Reputation: 791

How to display validation errors for array form fields in AngularJS?

I created a dynamic form where there are repeated fields submitted as an array. However, i want to validate each field individually and display the error message next to it. If i only have one row, it works fine, but once i add a second row, the first row stops displaying errors.

<form name='user' id='user' novalidate>
    <div ng-repeat="bonus in bonuses">
        <input name='codes[]' ng-model="bonus.code" lower-than="{{bonus.end_code}}" />
        <input name='end_codes[]' ng-model="bonus.end_code" />
        <span class="text-error" ng-show="user['codes[]'].$error.lowerThan">
            Code must be less than End Code.
        </span>
    </div>
</form>

AngularJS

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

app.controller('NewBonusController', function($scope) {
    $scope.bonuses = [];

    $scope.addFields = function () {
      $scope.bonuses.push({code:'', end_code: ''});
    }

    $scope.submit = function(){
        console.log($scope.bonuses);
    }
});


// Validate that one field is less or equal than other.
app.directive('lowerThan', [
  function() {

    var link = function($scope, $element, $attrs, ctrl) {

      var validate = function(viewValue) {
        var comparisonModel = $attrs.lowerThan;

        if(!viewValue || !comparisonModel){
          // It's valid because we have nothing to compare against
          ctrl.$setValidity('lowerThan', true);
        }

        // It's valid if model is lower than the model we're comparing against
        ctrl.$setValidity('lowerThan', viewValue <= comparisonModel );
        return viewValue;
      };

      ctrl.$parsers.unshift(validate);
      ctrl.$formatters.push(validate);

      $attrs.$observe('lowerThan', function(comparisonModel){
        return validate(ctrl.$viewValue);
      });

    };

    return {
      require: 'ngModel',
      link: link
    };

  }
]);

plunker: http://plnkr.co/edit/Fyqmg2AlQLciAiQn1gxY

I can settle for not having it next to each field, as long as changes to other field sets does trigger the error message properly in which case i can just pop it at the top. The main issue i see is that because they're arrays codes[] which are passed to the form at the end, they will not work properly.

The submit button is disabled properly on form validation, so i'm not sure why the message only locks onto the last row added.

Upvotes: 2

Views: 2005

Answers (1)

Karthik
Karthik

Reputation: 1377

Use a child form to separate the scope.

<ng-form name="frmChild">
  <input name='codes' ng-model="bonus.code" lower-than="{{bonus.end_code}}" />
  <input name='end_codes' ng-model="bonus.end_code" />
  <span class="text-error" ng-show="frmChild.codes.$error.lowerThan">
    Code must be less than End Code.
  </span>
</ng-form>

Upvotes: 4

Related Questions