I need to create several forms on a page based on a dynamic list I get from server. In order to do that I'm trying to use angular ng-repeat
like so:
<tr ng-repeat="row in data.rows" ng-show="row.edit" class="edit_row" style="border: 0;">
<td>
<div class="col-lg-9">
<form method="POST" class="form-horizontal" enctype="multipart/form-data" name="{{ row.row_id }}">
...
<input ng-disabled="{{ row.row_id }}.$invalid" value="Save" name="submit" type="submit" ng-click="collection.save_edit(row.row_id);">
</form>
</div>
</td>
</tr>
This doesn't work as expected - form has its name
attribute generated properly, but angular is not picking this up. Is there a way to create a form with dynamic name? Or is there a workaround for this issue?
Only idea that comes to my mind is to somehow create FormControllers
along with data.rows and use them in ng-repeat
but I couldn't find a way to do it either.
You could access form object from the this
context of the $scope method, which would represent the child scope anyways. Since it is dynamic form name you pass in the form name and form control will always be attached to the scope with the same name as that of the form. So you could do wither by accessing it on the method or using $scope[row.row_id].$invalid
explicitly on the view. Just to be safe i have use ng-attr-name
to expand interpolation and set the form name dynamically.
/*Get form object on save*/
$scope.save_edit = function(form){
console.log(this[form]);
}
/*Returns whether the form is valid or not*/
$scope.isInvalid = function(form){
return this[form].$invalid;
}
and your form would just be:
<form novalidate method="POST" class="form-horizontal" enctype="multipart/form-data"
ng-attr-name="{{ row.row_id }}">
<input type="text" name="test" ng-required="true" ng-model="row.test"/>
<input ng-disabled="isInvalid(row.row_id)" value="Save" name="submit"
type="submit" ng-click="save_edit(row.row_id);">
</form>
Side note: In order to be more specific and separate out the form specific functionality you could move these to another controller and set ng-controller
at the ng-repeat
level, with that you could just use $scope
instead of this
.