0

I have a form which represents an object and an array of sub-objects contained in a repeater. I want to dynamically add sub-objects to the array. When I add a sub-object the form gets submitted unexpectedly.

See this example:

http://plnkr.co/edit/TUblgmb7N710nPL7s5tU?p=preview

My form looks like this:

<form ng-submit="handleSubmit()" ng-controller="TestController">
  <div>Some Input: <input type="text"></div>  

  <div ng-repeat="obj in model.children">
    <input type="text" ng-model="obj.text" />
  </div>

  <button ng-click="addChild()"> Add Child</button>

</form>

The controller looks like this...

Controllers.controller('TestController', ["$scope", function($scope) {

  $scope.model = {
    name: "Some Text",
    children: []
  };

  $scope.handleSubmit = function() {
    alert("Form Submitted!");
  }

  $scope.addChild = function() {
    $scope.model.children.push({text:"Foo"});
  }


}]);

Click the "Add Child" buttton. The UI is updated as expected but the form gets submitted.

I can work around this by putting the submit function in ng-click on the Save button instead of ng-submit on the form but this seems like unexpected behaviour. Can anyone explain?

JohnnyD
  • 477
  • 1
  • 4
  • 19

1 Answers1

0

The default attribute type The HTML button tag <button>My Button</button> triggers the submit event as <input type = "submit"...> does.

Now, following the idea of @GruffBunny, I have added a pInputType parameter to your method to show what button was clicked:

$scope.addChild = function(pInputType) {
    $scope.model.children.push({text:"Foo", inputType : pInputType });
}

Then in the HTML block, the attribute inputTypewas added within the loop as follow:

<div ng-repeat="obj in model.children">
   <hr />
   <h3>{{obj.inputType}}</h3>
   <div>New Input: <input type="text" ng-model="obj.text" /></div>
</div>

Finally, here are the buttons for testing the code:

<!-- With Input Type -->
<h2>Input type Button</h2>
<input type="button" ng-click="addChild('Input type Button')" value="Btn Add Child" />
<hr />
<!-- With Normal Anchor -->
<h2>HTML Anchor</h2>
<a href="#" ng-click="addChild('HTML Anchor')">Add Child Link</a>
<hr />
<!-- Adding Bootstrap -->
<h2>HTML Bootstrap Anchor</h2>
<a href="#" ng-click="addChild('HTML Bootstrap Anchor')" class="btn btn-info"> Add Child Link</a>
<hr />
<!-- Button Tag -->
<h2>HTML Button Tag (Triggers SUbmit Events)</h2>
<button ng-click="addChild('Triggers Submit Events')">Add Child</button>
<hr />

Here is the complete plunker: http://plnkr.co/edit/N4hSjG

For further information about this behavior, you can read this Stack Overflow question: <button> vs. <input type="button" />. Which to use?

I hope it could be useful this explanation for anyone.