Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I set a form contained inside a ng-include to be prestine?

Tags:

angularjs

I have the following code:

<div modal="modal.shouldBeOpen" close="close()" options="opts">
    <div class="modal-body">
        <form novalidate name="itemForm" style="margin-bottom: 0px;">

Which is contained inside the included file modal.html

<div data-ng-controller="AdminController">
   <ng-include src="'/Content/app/admin/partials/grid-subject.html'"></ng-include >
   <ng-include src="'/Content/app/admin/partials/modal.html'"></ng-include>
</div>

In my AdminController controller I am trying to use the following code to reset the form to pristine:

$scope.itemForm.$setPristine();

When I do this it tells me that "itemForm" is undefined.

Is there a way I can set the contents of the form to pristine. I assume this is a scope problem but I am not sure how to fix it. I tried the one solution of removing the second include and pasting the code in directly. This solution works.

However we want to be able to reuse code so I would like to be able to do this with an include for modal.html

Note that the reason we would like to do this is because we have something like the following on our modal.html:

    <button
        class="btn float-right"
        data-ng-disabled="itemForm.$pristine"
        data-ng-click="modalReset()"
        data-ng-show="modal.resetButton">
        Reset</button>
</form>

So we are actually inside of the itemForm and would like to set it to $pristine from the button inside.

like image 852
Alan2 Avatar asked Jul 04 '13 15:07

Alan2


People also ask

What is Ng-pristine in angular?

ng-pristine: The ng-pristine class tells that the form has not been modified by the user. This returns true if the form has not been modified by the user. Return type: Return Boolean True if the form/input field is not modified by the user else it returns False.

What is the difference between Ng-dirty and Ng-pristine in angular?

ng-touched The field has been touched. ng-pristine The field has not been modified yet. ng-dirty The field has been modified.

What is the use of NG-include?

The ng-include directive includes HTML from an external file. The included content will be included as childnodes of the specified element. The value of the ng-include attribute can also be an expression, returning a filename. By default, the included file must be located on the same domain as the document.

What's the difference between dirty touched and pristine in a form element?

= pristine: This property returns true if the element's contents have not been changed. - dirty: This property returns true if the element's contents have been changed. - untouched: This property returns true if the user has not visited the element.


2 Answers

This answer will break all the rules (i.e., DOM traversal inside a controller), but here it is anyway...

.controller('AdminController', ['$scope','$element',
function($scope, $element) {
  $scope.$on('$includeContentLoaded', function() {
    var childFormController = $element.find('form').eq(0).controller('form');
    console.log(childFormController);
    childFormController.$setPristine();
  });
}]);

We wait for the ng-included content to load, then from the $element where AdminController is defined, we look for form elements, pick the first one, then get its FormController.

Plunker

If you are only calling $setPristine() as a result of some user interaction, you won't need to look for the $includedContentLoaded event – I only had to do that because I didn't want to create any UI component to trigger the operation, and when the controller first runs, the form doesn't exist yet.

See also AngularJS: Access formController of a form placed inside transcluded directive from parent controller which deals with the similar problem of trying to access a child from a parent.

A cleaner solution: define a directive (use it on the ng-include element) and pass it an AdminController function as an attribute. In the directive's link function, call that method and pass the FormController as a parameter. Then the AdminController will have a reference to the desired FormController. (I did not bother coding this up, as I'm not sure you want a solution where you have to use a directive along with ng-include.)

like image 104
Mark Rajcok Avatar answered Oct 24 '22 10:10

Mark Rajcok


Well, one way to do it is to broadcast an event, like so:

angular.module('myApp',[])
    .controller('AdminCtrl',function($scope){
        $scope.modalReset = function(){
            $scope.$broadcast('modal-reset');
        };
    })
    .controller('ModalCtrl', function($scope){
        $scope.$on('modal-reset', function(){
            $scope.itemForm.$setPristine();
        });
    });

This way you don't have to traverse the dom.

like image 31
Master Morality Avatar answered Oct 24 '22 09:10

Master Morality