0

I am learnig angular and I am trying to implement the following behavior using vanilla angular.

I have the following html page that creates dynamically text inputs and a button.

By pressing on the button I want to validate all the inputs (only to check if they are not empty) and show the message under the invalid input. It is very easy to implement with jQuery or even with plain JS, But I am struggling with angular.

jsFiddle - https://jsfiddle.net/AlexLavriv/zkdodm4b/1/

(function(angular) {
  'use strict';
angular.module('scopeExample', [])
  .controller('MyController', ['$scope', function($scope) {
    $scope.instances = [1,2,3,4,5,6,7,8,9,10];
$scope.clicked = function()
{
    alert("clicked");
};


  }]);
})(window.angular);



    <body ng-app="scopeExample">
      <div ng-controller="MyController">
     <div ng-repeat="instance in instances">
    <form name="instance{{$index}}">
    <input type="text" required="true" ng-model="txt" name="txt">
    <div ng-show="instance{{$index}}.txt.$invalid && instance{{$index}}.txt.$touched"> the input is illegal</div>

    </form>
    </div>
    <input type="button" value="Press"  ng-click="clicked()">


</div>
</body>
2
  • To be honest there are quite a few things wrong with your code, particularly your use of AngularJS directives in your HTML. You should take a look at the AngularJS forms documentation and try out a few of the examples. Commented Mar 19, 2017 at 23:19
  • Thank you for commenting, I have read that documentation, and honestly I don't understand what i did wrong. I also read an article in w3c school about the angular validation and it seems the right way. I am really interested in your answer. Thanks in advance. Commented Mar 20, 2017 at 6:19

2 Answers 2

1

This should give you what you're looking for (just a few tweaks):

(function(angular) {
  'use strict';
  angular.module('scopeExample', [])
    .controller('MyController', ['$scope', function($scope) {
      $scope.instances = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
      $scope.clicked = function() {
        angular.forEach($scope.instances, function(instance) {
          $scope.outerForm[instance].txt.$setTouched();
        });
      };
    }]);
})(window.angular);
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<body ng-app="scopeExample">
  <div ng-controller="MyController">
    <form name="outerForm">
      <div ng-repeat="instance in instances">
        <ng-form name="{{instance}}">
          <input type="text" required="true" ng-model="txt" name="txt">
          <div ng-show="{{instance}}.txt.$error.required && {{instance}}.txt.$touched"> the input is illegal</div>
        </ng-form>
      </div>
      <input type="button" value="Press" ng-click="clicked()">
    </form>
  </div>
</body>

Let me know if you have any further questions.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you very much ! You definitely solved my issue. But I keep wondering is there more angular way to do it? Because it feels like a jQuery implementation through angular code.
Glad it worked out, no worries. Can be a little more specific when you say, is there a more angular way to do it and it feels like a jQuery implementation? What makes you think that?
Well, I believe the whole page/form should have only one validation variable, maybe some thing like $scope.isformValid = txt1.$valid && txt2.$valid && txt3.$valid and so on, every input should be binded (bound?) to that variable. And instead of iterating through all instances of the inputs and activating the validation (by calling the setTouch) there should be a global function that does it for the whole page/form. Maybe it is nonsense, but I think it is more angular way.
It really does depend on your use case. Take a look at this, docs.angularjs.org/api/ng/type/ngModel.NgModelController.
0

Some observations as per current code :

  • As we are repeating only form element <input>. so, put ng-repeat below<form> instead of outside.
  • <input type="submit" value="Press" ng-click="submitted = true"> should comes under the form element.
  • use <input name="txt{{$index}}".. instead of <form name="instance{{$index}}"...

DEMO

var app = angular.module('scopeExample', []);
app.controller('MyController', ['$scope', function($scope) {
    $scope.instances = [1,2,3,4,5];
    $scope.clicked = function() {
      alert("clicked");
    };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="scopeExample" ng-controller="MyController">
<form name="myForm" ng-submit="myForm.$valid && clicked()" novalidate>
<div ng-repeat="instance in instances">
<input type="text" required="true" ng-model="txt" name="txt{{$index}}">
<div ng-show="submitted == true && myForm.txt{{$index}}.$error.required"> the input is illegal</div>
</div>
<input type="submit" value="Press"  ng-click="submitted = true">
</form>
</div>

1 Comment

Thank you so much ! It is perfect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.