19

I have a form that I wanted be nested, but it is not possible since HTML can't accept nested form. Is there a way I can manually invoke the submit(triggers the validation, e.g. required) on first form on AngularJS?

Here's how the code looks like:

<div ng-conroller="ContactController">

    <form ng-submit="saveHeaderAndDetail()">
        <label for="Description">Description</label>
        <input type="text" ng-model="Description" required/> 

        <input type="text" style="visibility:hidden" />
    </form>

    <form ng-submit="addToDetail()">
    ... 
    </form>

    <input type="button" 
        ng-click="what code could trigger the first form's submit?"/>

</div>

Btw, both forms are under one controller if that helps

1
  • ng-submit binds the 'submit' event to an element.. and AFAIK, this should be attached to a button or input[type=submit] or input[type=button] DOM node, shouldn't it ? Commented Nov 14, 2012 at 16:05

5 Answers 5

9

Try creating a directive that catches an event:

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

function MyCtrl($scope) {
    $scope.triggerSubmit = function() {
        $scope.$broadcast('myEvent');
        console.log('broad');
    };
    
    $scope.onSubmitted = function() {
        alert('submitted!');
    };
}


app.directive('submitOn', function() {
    return {
        link: function(scope, elm, attrs) {
            scope.$on(attrs.submitOn, function() {
                //We can't trigger submit immediately, or we get $digest already in progress error :-[ (because ng-submit does an $apply of its own)
                setTimeout(function() {
                    elm.trigger('submit');
                });
            });
        }
    };
});
<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet"/>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://code.angularjs.org/1.0.0/angular-1.0.0.js"></script>
<div ng-controller="MyCtrl">
    <form submit-on="myEvent" ng-submit="onSubmitted()">
        Form...
    </form>
    <hr />
    <a class="btn" ng-click="triggerSubmit()">Submit</a>
</div>

Original source:

http://jsfiddle.net/unWF3/
Sign up to request clarification or add additional context in comments.

2 Comments

Your code on the button that doesn't belong to form triggers the submit, which is good, new learning to me, +1 there. But it doesn't trigger the validation on that form. See what I meant with validation jsfiddle.net/unWF3/6
is there a way to do this without including jquery?
6

I've answered a similar question here AngularJS - How to trigger submit in a nested form

Basically, you can trigger validation by firing $validate event

isFormValid = function($scope, ngForm) {
    $scope.$broadcast('$validate');
    if(! ngForm.$invalid) {
      return true;
}

For working code example & a small utility method which is helpful in showing validation messages, see answer in the above link.

1 Comment

does not work if you have a form with ng-submit, a <button type="submit"> and a <button type="button"> with a manual ng-click in which you call $scope.$broadcast('$validate');
4

You can have nested forms with ng-form directive. It will be like:

<form name="accountForm">
  <div data-ng-form="detailsForm">
    <input required name="name" data-ng-model="name">
  </div>
  <div data-ng-form="contactsForm">
    <input required name="address" data-ng-model="address">
  </div>
  <button type="submit">Save</button>
</form>

That way when submit will be triggered for the accountForm it will validate nested ng-forms also.

Comments

3

There's an easier way to do that, You can give a name for each form that you have in your app, then you'll be able to send the entire angular object of the form that you want to trigger or do whatever you want with it. Example:

<div ng-conroller="ContactController">

    <form name="myFirstForm" ng-submit="saveHeaderAndDetail()">
        <label for="Description">Description</label>
        <input type="text" ng-model="Description" required/> 

        <input type="text" style="visibility:hidden" />
    </form>

    <form name="mySecondForm" ng-submit="addToDetail()">
    ... 
    </form>

    <input type="button" 
        ng-click="saveHeaderAndDetail(myFirstForm)"/>

</div>

Then in your function

saveHeaderAndDetail (myFirstForm) {
myFirstForm.$submitted = true
...
}

Comments

1

We can always submit a form directly using the submit () function from javascript.

document.getElementById("myform").submit()

In this way, we can validate the form using angularjs first and if the form is valid then submit it using the submit method.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.