henriquat.re is an interesting project on AngularJS from the .net developer’s point of view. Their article on Combining AngularJS with existing Components gives an elegant approach to combine JQuery UI datepicker fragment and move it to a reusable AngularJS directive.
When I tried the code with the latest AngularJS and JQuery UI releases the code did not work. I researched and found the problem. As stated in AngularJS Migrating from Previous Versions
“Due to 3f2232b5,
To migrate, register your controllers with modules rather than exposing them as globals:”
I also used the idea given in Stackflow question Adding directive makes controller undefined in angular js code answered by James Allardice.
My modified code is given below
HTML index.html
demo.js
/* Embedded Fragment - controller */
References
When I tried the code with the latest AngularJS and JQuery UI releases the code did not work. I researched and found the problem. As stated in AngularJS Migrating from Previous Versions
“Due to 3f2232b5,
$controller
will no longer look for controllers on window
. The old behavior of looking on window
for controllers was originally intended for use in examples, demos, and toy apps. We found that allowing global controller functions encouraged poor practices, so we resolved to disable this behavior by default. To migrate, register your controllers with modules rather than exposing them as globals:”
I also used the idea given in Stackflow question Adding directive makes controller undefined in angular js code answered by James Allardice.
My modified code is given below
HTML index.html
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> <script src="http://code.jquery.com/jquery-1.10.2.js"></script> <script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <!-- <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css"> <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script> --> <!-- Embedded Fragment - maindiv --> <div ng-app="demo" ng-controller="DemoController"> Date Of Birth: <my-datepicker type="text" ng-model="user.dateOfBirth" /> <br> Current user's date of birth: <span id="dateOfBirthDisplay">{{user.dateOfBirth}}</span> </div> <!-- Fragment End - maindiv --> <!--<script src="angular.js"></script>--> <!-- <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>--> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script> <script src="demo.js"></script> <link rel="stylesheet" href="demo.css">JavaScript
demo.js
/* Embedded Fragment - controller */
//function DemoController($scope) { // $scope.user = { // dateOfBirth: new Date(1970, 0, 1) // } //} // var demo = angular.module("demo", []); // demo.controller("DemoController", function($scope) { $scope.user = { dateOfBirth: new Date(1970, 0, 1) } }); /* Fragment End - controller */ /* Embedded Fragment - directive */ demo.directive('myDatepicker', function ($parse) { return { restrict: "E", replace: true, transclude: false, compile: function (element, attrs) { var modelAccessor = $parse(attrs.ngModel); var html = "<input type='text' id='" + attrs.id + "' >" + "</input>"; var newElem = $(html); element.replaceWith(newElem); return function (scope, element, attrs, controller) { var processChange = function () { var date = new Date(element.datepicker("getDate")); scope.$apply(function (scope) { // Change bound variable modelAccessor.assign(scope, date); }); }; element.datepicker({ inline: true, onClose: processChange, onSelect: processChange }); scope.$watch(modelAccessor, function (val) { var date = new Date(val); element.datepicker("setDate", date); }); }; } }; }); /* Fragment End - directive */
References