Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check an ng-included form's validity from the parent scope?

I have a subform that is shared among multiple views in my app. In one view, this subform is displayed alone with a back/continue button at the bottom that leads the user to the next subform. In another view, the subform is displayed on the same page as other subforms (basically one long form).

Since the html of the subform is 100% identical in both views, I separated it into a partial and am using ng-include to render it. In the view that displays only the subform with the back/continue buttons, I render the back/continue buttons within the parent's HTML.

Visually, everything works fine, and I'm able to access all of the data entered in the form (user.email, user.password, user.etc...).

The problem is that I'm enabling/disabling the "continue" button based on whether or not the user has completed the form correctly, and this does not work in the "subform-only" variation because the parent scope doesn't seem to be able to access the form's status. If I stick the buttons in the partial, it works, but I don't want to do that because the buttons don't belong there in every instance that this partial is being used.

JSFiddle Example

Notice in my example that the submit button within the red border is disabled until something is typed in the box and the "Form Invalid?" value updates, while the button within the blue border is always enabled and the "Form Invalid?" value is blank.

How can I access the value of myForm.$invalid from the parent scope?

like image 575
Michael Moussa Avatar asked Apr 04 '13 18:04

Michael Moussa


People also ask

What is$ setPristine?

$setPristine();Sets the form to its pristine state. This method sets the form's $pristine state to true, the $dirty state to false, removes the ng-dirty class and adds the ng-pristine class. Additionally, it sets the $submitted state to false.

Can you describe what scope is in angular?

AngularJS Scope The scope is the binding part between the HTML (view) and the JavaScript (controller). The scope is an object with the available properties and methods. The scope is available for both the view and the controller.

What is scope and rootScope?

All the $scopes of an AngularJS application are children of the $rootscope. An app can have only one $rootScope. It is the scope that is created on the HTML element that contains the ng-app directive and is available in the entire application. Example 3: Understanding the working of $scope and $rootScope.

What is parent scope in AngularJS?

Angular scopes include a variable called $parent (i.e. $scope. $parent ) that refer to the parent scope of a controller. If a controller is at the root of the application, the parent would be the root scope ( $rootScope ). Child controllers can therefore modify the parent scope since they access to it.


2 Answers

The child scope created when you use ng-include is hiding the form functions from the parent.

In addition to using a directive, you can also add an object in the parent, but it's important to set the name of the form to an object with a property like so:

<form name="myFormHolder.myForm">

and in the parent controller

$scope.myFormHolder = {};

then the following should work:

$scope.myFormHolder.myForm.$pristine

This way when the form is evaluated, myForm.$valid will get set on the parent. I believe I asked this same question: Why form undefined inside ng-include when checking $pristine or $setDirty()?

like image 137
Scott Driscoll Avatar answered Oct 19 '22 07:10

Scott Driscoll


If it's a sub-form you can just move the form-tag from the sub-form and into the main-form: updated JSFiddle

You could also nest your forms using the ngForm-directive:

In angular forms can be nested. This means that the outer form is valid when all of the child forms are valid as well. However browsers do not allow nesting of elements, for this reason angular provides ngForm alias which behaves identical to but allows form nesting.

The result is a bit messy imo. I'd rather create a 'myForm'-directive with a new scope to avoid using $parent - something like:

myApp.directive('myForm',function(){
    return{ 
        restrict:'E',
        scope:{model:'='},
        templateUrl:'/form.html',
        replace:true
    }
});

- see this JSFiddle example

like image 23
joakimbl Avatar answered Oct 19 '22 05:10

joakimbl