4

I have to do form validation for multiple forms which have to be created dynamically. I have created the forms dynamically by using ng-repeat but I am not able to access that form in controller.

Please check the code:

 <button ng-click="navigate()">Next</button>
   <div ng-repeat="service in services">
     <ng-form name="mainform">
        <div ng-repeat="spec in service.products">
           <ng-form name="subform">
               <input type="text" name="{{spec.name}}" ng-model="spec.value">
               <span ng-show="subform[spec.name].$invalid">please enter</span>
           </ng-form>
        </div>
    </ng-form> 
  </div >

It is working fine, but I need to check whether at least one of mainform's subforms is valid or not after clicked on next button so I have tried to access this in controller like this:

 $scope.navigate=function(){
     console.log($scope.mainform.subform);
     console.log($scope.subform);
 }

but I am getting undefined for both console logs. How can I access multiple dynamically created forms in the controller?

Heretic Monkey
  • 10,498
  • 6
  • 45
  • 102
silvesterprabu
  • 1,267
  • 8
  • 25
  • 46

3 Answers3

1

What exactly do you want to do with forms in controller?

Looks like you don't need it.

You have forms hierarchy. Pseudocode:

ng-form mainForm
  ng-form subFormOne
  ng-form subFormTwo

If subFormOne or subFormTwo is invalid then mainForm will be invalid too. If all sub forms are valid then mainForm will be valid too. You will check only mainForm.$valid in your code.

If you need to style it somehow you I recommend you to use css there. ngForm directive adds classes to the element. You can use .ng-form selector in css to add styles to your form. For example:

.ng-form.ng-invalid {
  background-color: #ff0000;
} 

Here is plunkr example.

Sharikov Vladislav
  • 6,110
  • 4
  • 39
  • 78
  • controller file how to do that ? ....I have tried like this but getting error ... – silvesterprabu Dec 06 '16 at 19:44
  • $scope.navigate=function(){console.log($scope.mainform.$invalid)} – silvesterprabu Dec 06 '16 at 19:45
  • I added the plunkr example – Sharikov Vladislav Dec 06 '16 at 19:48
  • If you have form name "mainForm" you have to use: `console.log($scope.mainForm.$inva‌​lid)` – Sharikov Vladislav Dec 06 '16 at 19:54
  • in your code mainform is not a ng-repeat one ...it is kind of static ...but if you look at my code there is two form one is mainform another one is subform both will be created using ng-repeat ...you code won't work when there is both forms are dynamically created ... – silvesterprabu Dec 06 '16 at 20:14
  • Yes `mainForm` is not in ngRepeat, like in your code. Your `mainform` is not in ngRepeat too. When you have hierarchy you don't care how many forms there are in ngRepeat. Thats the main point. If you will see my plunkr example you will get that I have 3 subsforms which are dynamically created by ngRepeat. Exactly like in your code. – Sharikov Vladislav Dec 06 '16 at 20:28
  • You said you need to access subforms for controller. I asked you why? The answer was: to get if they are invalid. You can check if **all** forms are valid or **not** valid by checking parent form `mainForm`. The solution is in my plunkr. – Sharikov Vladislav Dec 06 '16 at 20:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/129971/discussion-between-silvesterprabu-and-sharikov-vladislav). – silvesterprabu Dec 07 '16 at 06:59
1

The logs show undefined because because the ng-repeat directive creates child scopes and the forms are put on those child scopes.

Create a form at the top level, above the ng-repeat:

<button ng-click="navigate()">Next</button>

<!-- ADD top form above ng-repeat -->
<ng-form name=top>
    <div ng-repeat="service in services">
        <ng-form name="mainform_{{$index}}">
            <div ng-repeat="spec in service.products">
                 <ng-form name="subform_{{$index}}">
                     <input name="{{spec.name}}" ng-model="spec.value">
                 </ng-form>
            </div>
        </ng-form> 
    </div>
</ng-form>

Then forms inside the ng-repeat will be visible:

$scope.navigate=function(){
     console.log($scope.top);
     console.log($scope.top.mainform_0);
     console.log($scope.top.mainform_0.subform_0);
};

The DEMO on PLNKR

georgeawg
  • 46,994
  • 13
  • 63
  • 85
0

I would use $index from ng-repeat or something makes it unique.

UPDATE: 12/6/2016 Based on the comment.

plnkr of deeply nested dynamic forms and validation

<button ng-click="navigate()">Next</button>
<div class="outer" ng-repeat="service in services" ng-init="serviceSuffix=$index;serviceForm = 'form' +serviceSuffix">
  <h2>{{service.serviceName}} id= {{service.id}} {{serviceForm}}</h2>

  <ng-form name="{{serviceForm}}">
    <button ng-click="isValidForm(serviceSuffix)">Is Outer valid</button>
    <div class="inner" ng-repeat="spec in service.products" ng-init="specSuffix = serviceSuffix+'_'+$index; specForm = 'form' +specSuffix; ">
      <h2>{{spec.specName}} id={{spec.id}} {{specForm}}</h2>
      <ng-form name="{{specForm}}">
        <input required type="text" name="{{spec.specName}}" ng-model="spec.value">
        <span ng-show="this[specForm][spec.specName].$invalid">please enter</span>
        <button ng-click="isValidForm(specSuffix)">Is Inner valid</button>
      </ng-form>
    </div>
  </ng-form>
</div>

To access nth form in your controller.

  $scope.isValidForm = function(suffix) {
    alert('form '+suffix+' valid='+$scope['form' +suffix].$invalid)
  };
bhantol
  • 8,420
  • 4
  • 40
  • 73
  • ya I agree . but how to check this in controller ? – silvesterprabu Dec 06 '16 at 19:33
  • Giving one example but it would be best if you come with how and where do you want to check a particular form. – bhantol Dec 06 '16 at 19:40
  • when i click on next button I need to check whether any one the main form is valid or not – silvesterprabu Dec 06 '16 at 19:41
  • You can access any of the forms using the form suffix. Also you need to know the name of the form before checking valid or invalid. So if you know the form suffix Next button can check valid or invalid. – bhantol Dec 06 '16 at 20:51
  • I don't want to have these many buttons in this html...I need only one button that is there in top (navigate) . – silvesterprabu Dec 07 '16 at 09:09
  • Those additional buttons are for demonstration only. They are not the solution. For Next button you can iterate over index of all services array an reconstruct the suffix to get a form name. However you don't have any fields in your mainForm. Nested forms are discouraged. – bhantol Dec 07 '16 at 13:06