Squazz
Squazz

Reputation: 4171

How to let ngForm know that the form it is nested in have been submitted

What I know

In Angular 1.3 and above I have access to $submitted that can tell me if the form in question have been submitted. This works fine and dandy when working with a form in a way like this:

<form name="myForm" ng-submit="register();" novalidate>
    <div>
        <input placeholder="First Name" name="name" type="text" ng-model="user.firstName" required />
        <span ng-show="myForm.$submitted && myForm.name.$error.required"> First Name is required</span>
    </div>
    <ng-form name="subForm">
        <div>
            <input placeholder="Last Name" name="lastName" type="text" ng-model="user.Name" required />
            <span ng-show="myForm.$submitted && subForm.lastName.$error.required"> Last Name is required</span>
        </div>
    </ng-form>
    <input type="submit" value="Save" />
</form>

The problem

But if I generate the ng-form dynamically, and therefore do not know the name of the form that the ng-form is nested in, I'm running into problems when I want to know if the parent have been submitted. I want this information so I can use it as a parameter for when to show a validation error message for the input in the nested ng-form.

Say I have a directive that i want to use as part of my form.

Index file

<!doctype html>
<html lang="en">
<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>

  <script src="lastNameDirective.js"></script>
</head>

<body ng-app="formExample">
  <form name="myForm" novalidate>
      <input placeholder="First Name" name="name" type="text" ng-model="user.firstName" required />
      <span ng-show="myForm.$submitted && myForm.name.$error.required"> First Name is required</span><br />
      <last-Name></last-Name>
      <br />
      <input type="submit" value="Save" />
  </form>
</body>
</html>

Directive

angular.module('formExample', [])
  .directive('lastName', function() {
    return {
      restrict: 'E',
      templateUrl: 'my-template.html'
    };
  });

Template

<ng-form name="subForm">
    <input placeholder="Last Name" name="lastName" type="text" ng-model="user.Name" required />
    <span ng-show="subForm.$submitted && subForm.lastName.$error.required"> Last Name is required</span>
</ng-form>

How do I get around this situation? Is there any way to either dynamically get the name of the form my ng-form is nested in, or can I somehow listen for a submit on my parent form?

A little plunker to play around with

What I have looked at

I have tried looking at RealCrowds Angular-Utilities, and is using this in my current project (as I have been using Angular 1.2 up till now), but it doesn't seem like they can handle the scenario either. (Even though there have been some talk about it)

Upvotes: 0

Views: 898

Answers (2)

Stefan Hans Schonert
Stefan Hans Schonert

Reputation: 647

Require the parents formController within the directive, and expose it.

....directive('lastName', function() {
  return {
    restrict: 'E',
    templateUrl: 'my-template.html',
    require:'^form',
    link:link
  };

  function link(scope, element, attrs, formCtrl) {
    scope.parentForm = formCtrl;
  }
});

http://plnkr.co/edit/pKonBjl57bjp4PaokARV


Would suggest exposing the parents formController through the controllerAs syntax - assuming the main form has a controller. Leaner markup and no need for the require example shown above

Upvotes: 1

Illia Olenchenko
Illia Olenchenko

Reputation: 128

Squazz!

I guess i have a solution for you:
as i saw on plunkr second span was hide all the time.
The mark is that your submit button is assigned to the main form, and when you check $submit on a subForm it was not submitted, because there is no <submit> for the subForm.
so as i understood you can check a main form all time. Your fork.

Hope i helped.

Upvotes: 0

Related Questions