Johnathan Johnathan - 3 months ago 19
AngularJS Question

I am trying to call a function within my Angular directive

I am new to Angular, and I want to re-write/improve my ASP.NET app with Angular to become a better programmer. I am starting small by creating a top banner where the user can choose a startDate and endDate (that will be sent to a web service) from pop-up calendars (Pikaday.js). The problem is that I can't seem able to call this function within my directive's template:

webform:

<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="scripts/angular.min.js"></script>
<script src="scripts/myAngularApp.js"></script>
<link href="css/myStyleSheet.css" rel="stylesheet" />
<link href="css/bootstrap.css" rel="stylesheet" />
<script src="scripts/myFunctions.js"></script>

</head>

<body data-ng-app="myApp">
<top-banner></top-banner>
</body>
</html>


myAngularApp.js

/// <reference path="angular.min.js"
/// <reference path="bootstrap.min.js" />
/// <reference path="Pikaday/pikaday.js" />
/// <reference path="myFunctions.js" />

var myApp = angular.module('myApp', []);
myApp.directive('topBanner', function () {
var template = "<div class='row'>\
&ensp;Report from:&emsp;\
<input type='text' id='startDate' size='6'/>&emsp;To\
&emsp;<input type='text' id='endDate' size='6'/>&emsp;\
<input type='button' value='Go'>\
</div>";
return {
template,
restrict: 'E'
};
});


The pikaday function:

function loadPikaday() {
var picker = new Pikaday({
field: document.getElementById("startDate"),
firstDay: 1,
format: "YYYY-MM-DD",
minDate: new Date('2000-01-01'),
maxDate: new Date('2020-12-31'),
yearRange: [2000, 2020],
numberOfMonths: 2
});

var picker = new Pikaday({
field: document.getElementById("endDate"),
firstDay: 1,
format: "YYYY-MM-DD",
minDate: new Date('2000-01-01'),
maxDate: new Date('2020-12-31'),
yearRange: [2000, 2020],
numberOfMonths: 2
});
}


I would like my function to work on the elements of the template variable in my directive. I get the following page, which is exactly what I want but without the pop-up Pikaday calendar when I click in the text fields. I would greatly appreciate the community's feedback. Thank you!

enter image description here

Ted Ted
Answer

So you're probably going to have to create a controller and ideally a service.

If you don't know what those are, check this article out- should give you a good intro into AngularJS.

Ok, so now you'll want to actually create a new controller and attach it to your app module. You could actually go ahead and toss in the pikaday function in the controller, and call it by linking your directive to your controller by adding another parameter in your directive under restrict as:

   return {
       template: template,
       restrict: 'E',
       controller: 'controller',
       controllerAs: 'ctrl'
   }

Once you have that in place, you can go ahead and attach the pikaday function to your controller and access it in your directive by adding this tag in your element:

  "ng-click='loadPikaday()'"

If this seems really confusing to you, I'd recommend giving that article I tagged above a good read and things you should clear up a little. That article really outlines the build of AngularJS apps and how the different components work together.

Hope this helped!

EDIT: On a side note, it's generally bad practice to manipulate the DOM in controllers, so you should the pikaday function into a service, but for a quick fix, this should work.