I have one main form and another subForm
. How I can access $error
of the child form but without having to directly reference the subForm name?
I want to be able to display that name is required
(for example) instead of just knowing the name of the form.
Here's a demo of my problem: http://plnkr.co/edit/QWZArI1UFPpJdjoK8eVn?p=preview
Ok, I wasn't 100% sure I understood your question, but I think I do, so here's a stab at it:
There are a couple ways to access the errors of a child form, but all seem to need the name of the ngForm
.
Assuming this structure:
<form name="parentForm">
<ng-form name="childForm"></ng-form>
</form>
you know that you can access it via $scope.childForm.$error
, but less known is that it is also attached to the parent form. You can access it with $scope.parentForm.childForm.$error
, but obviously, that's no good, since you still need the name.
You could get hacky and loop through the properties on the parent form and try to tell which one is the child form and go from there.
Lastly, as we've discussed on Twitter/GitHub, I have a directive that kinda does some of this magic for you. It did have a bug that didn't handle embedded forms correctly, but I fixed it. Check out the new version of my directive that tries to simplify handling errors with Angular:
https://github.com/CWSpear/angular-form-errors-directive
I added the ability to display all the errors of all the child ngForms
with a flag in v1.3.0
.
I think for this particular use case, my simple getErrors
method on the scope is a more robust solution than the formErrors
directive proposed in the accepted answer. Have a look at this comparison of the two solutions. The formErrors
directive will clear errors from the child forms if the bottom child form is filled out. Play around with data entry and you will quickly see other bugs.
The getErrors
solution is not pretty, but it is very simple and one can easily see how it might be improved to provide clearer messages.
The JavaScript:
var app = angular.module('app', ['FormErrors']);
app.controller('MainCtrl', ['$scope', function ($scope) {
$scope.people = [{name: ''}, {name: ''}];
$scope.allErrors = [];
$scope.getErrors = getErrors;
function getErrors(formObject){
$scope.allErrors = [];
extractErrors(formObject)
}
function extractErrors(formObject, parent) {
for (var e in formObject.$error) {
var path = parent ? parent + "." + e + "." + formObject.$name : formObject.$name + "." + e;
var err = formObject.$error[e];
if (err instanceof Array){ // this is an array of sub-forms
err.forEach(function (subForm, i) {
extractErrors(subForm, path + "[" + i + "]");
});
} else {
if (err === true) {
path = path.replace(new RegExp("." + e, "g"), "");
$scope.allErrors.push(path + ": " + e);
}
}
}
}
}]);
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