Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access the FormController when the form is in a directive?

The below is my directive:

restrict: 'E',
scope: {

},
templateUrl: 'directives/my.directive.html',
link: function(scope) { 
    // Want to be able to access "myForm" here (eg: to setPristine(), etc)
    scope.bla = {}
}

And the following is in the template:

<form name="myForm" novalidate>
    <input name="inputOne" type="text" ng-model="bla.name" required/>
</form>

I have tried:

console.log(scope.myForm) // shows undefined

and:

<form name="myForm" novalidate>
    <div ng-init="bla.newForm = myForm"></div>

    <input name="inputOne" type="text" ng-model="bla.name" required/>
</form>

console.log(scope.bla.newForm) // Undefined

Please don't tell me to:

require: '^form' 

I get error: Unable to get FormController. Which is correct as the form is part of the directive and not in the parent template/scope

Really appreciate some help here.

like image 618
Kiong Avatar asked Mar 13 '23 15:03

Kiong


2 Answers

A really easy way to get the form controller from a form, regardless of scope (or if you need to access it from another controller, service, or directive!), is to use angular.element.

angular.element("[name='myForm']").controller("form");

The caveat here is that the form has to have been loaded/compiled into the DOM, but since you're doing this in your link function it should be already rendered. If you get undefined, try wrapping it in a $timeout to give the digest a chance to run.

 $timeout(function() { angular.element("[name='myForm']").controller("form"); });

This isn't very "best practice" but it's great if you've exhausted other options.

like image 159
Scott Byers Avatar answered Apr 26 '23 06:04

Scott Byers


scope.myForm should be available from within your directive's controller/link function.

Here is an example:

var app = angular.module('app',[]);
app.directive('myDirective', function() { 
  return {
     restrict: 'E',
     scope: {},
     template: '<form name="myForm"></form>',
     link: function(scope, element, attr) {
       alert("scope.myForm is available: " + scope.myForm);
       alert("so is $setPristine():" + scope.myForm.$setPristine);
       alert("so is $error object: " + scope.myForm.$error);
     }
  }
  
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
   <my-directive></my-directive>
</div>
like image 43
pixelbits Avatar answered Apr 26 '23 06:04

pixelbits