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/
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); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With