Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: Fields added dynamically are not registered on FormController

I have the following static form in AngularJS:

<form name="myForm" class="form-horizontal">    <label>First Name:</label>   <input type="text" name="first_name" ng-model="entity.first_name">    <label>Last Name:</label>   <input type="text" name="last_name" ng-model="entity.last_name">  </form> 

Angular creates a FormController for me and publishes it into the scope (under the form name). Which means I have access to properties like the following:

$scope.myForm.first_name.$error $scope.myForm.last_name.$invalid ... 

This is super useful!

But in my case I'm building a form dynamically, using directives:

<form name="myForm" class="form-horizontal">    <field which="first_name"></field>   <field which="last_name"></field>  </form> 

The <field> directives don't resolve to actual <input> elements until after a while (after I've fetched some data from the server, linked the directives, etc.).

The problem here is that no field properties are defined on the form controller, as if dynamic fields didn't register with the FormController:

// The following properties are UNDEFINED (but $scope.myForm exists) $scope.myForm.first_name $scope.myForm.last_name 

Any idea why? Any solution/workaround?

You can see the entire code in this jsFiddle:
http://jsfiddle.net/vincedo/3wcYV/

like image 314
AngularChef Avatar asked Apr 05 '13 21:04

AngularChef


1 Answers

Update 7/31/2015 This has been fixed since 1.3, see here: https://github.com/angular/angular.js/issues/1404#issuecomment-125805732

Original Answer This is unfortunately a short coming of AngularJS at the moment. Angular's form validation doesn't work with dynamically named fields. You can add the following at the bottom of your HTML to see exactly what's going on:

<pre>{{myForm|json}}</pre> 

As you can see, Angular isn't getting the dynamic input name right. There's currently a work around involving nested forms that can get kind of nasty, but it does work and (with a little extra work) will submit the parent form without trouble.

If you want, you can go drum up more support for the issue: GitHub Issue - dynamic element validation. Either way, here's the code:

http://jsfiddle.net/langdonx/6H8Xx/2/

HTML:

<div data-ng-app>     <div data-ng-controller="MyController">         <form id="my_form" name="my_form" action="/echo/jsonp/" method="get">             <div data-ng-repeat="field in form.data.fields">                 <ng-form name="form">                     <label for="{{ field.name }}">{{ field.label }}:</label>                     <input type="text" id="{{ field.name }}" name="{{field.name}}" data-ng-model="field.data" required>                     <div class="validation_error" data-ng-show="form['\{\{field.name\}\}'].$error.required">Can't be empty.</div>                  </ng-form>             </div>             <input type="submit" />         </form>     </div> </div> 

JavaScript:

MyController.$inject = ["$scope"];  function MyController($scope) {     $scope.form = {};     $scope.form.data = {};     $scope.form.data.fields = []      var f1 = {         "name": "input_1",         "label": "My Label 1",         "data": ""     };     var f2 = {         "name": "input_2",         "label": "My Label 2",         "data": ""     };      $scope.form.data.fields.push(f1);     $scope.form.data.fields.push(f2); } 
like image 157
Langdon Avatar answered Sep 22 '22 14:09

Langdon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!