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?

4
  • Shouldn't it be <ng-form [name="mainform"]> ? Commented Dec 6, 2016 at 19:07
  • What exactly do you want to do with these forms in controller? Commented Dec 6, 2016 at 19:34
  • I want to check in controller that at least any one of the mainform has all valid data in subform Commented Dec 6, 2016 at 19:38
  • This probably is one of the reasons HTML disallows nested forms.... Commented Dec 6, 2016 at 21:09

3 Answers 3

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.

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

8 Comments

controller file how to do that ? ....I have tried like this but getting error ...
$scope.navigate=function(){console.log($scope.mainform.$invalid)}
I added the plunkr example
If you have form name "mainForm" you have to use: console.log($scope.mainForm.$inva‌​lid)
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 ...
|
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

Comments

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)
  };

6 Comments

ya I agree . but how to check this in controller ?
Giving one example but it would be best if you come with how and where do you want to check a particular form.
when i click on next button I need to check whether any one the main form is valid or not
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.
I don't want to have these many buttons in this html...I need only one button that is there in top (navigate) .
|

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.