1 | /*
|
---|
2 | Map module directives
|
---|
3 | */
|
---|
4 | (function (ng, $) {
|
---|
5 |
|
---|
6 | var reinitialiseJscroll = function ($element) {
|
---|
7 | var jscrollApi = $element.data('jsp');
|
---|
8 | if (jscrollApi) {
|
---|
9 | setTimeout(function () {
|
---|
10 | jscrollApi.reinitialise();
|
---|
11 | }, 0);
|
---|
12 | } else {
|
---|
13 | $element.jScrollPane({ maintainPosition: false, mouseWheelSpeed: 30, verticalDragMinHeight: 30 });
|
---|
14 | }
|
---|
15 | };
|
---|
16 |
|
---|
17 | angular.module('mapModule')
|
---|
18 | // data-google-map
|
---|
19 | .directive('googleMap', ['$window', '$timeout', 'utils', function ($window, $timeout, utils) {
|
---|
20 | return {
|
---|
21 | restrict: 'A',
|
---|
22 | scope: {
|
---|
23 | googleMapModule: "=googleMap" // two-way binding with controller e.g. MapCtrl
|
---|
24 | },
|
---|
25 | link: linker
|
---|
26 | };
|
---|
27 |
|
---|
28 | function linker(scope, element, attrs) {
|
---|
29 |
|
---|
30 | scope.safeApply = function (fn) {
|
---|
31 | var phase = this.$root.$$phase;
|
---|
32 | if (phase == '$apply' || phase == '$digest') {
|
---|
33 | if (fn && (typeof (fn) === 'function')) {
|
---|
34 | fn();
|
---|
35 | }
|
---|
36 | } else {
|
---|
37 | this.$apply(fn);
|
---|
38 | }
|
---|
39 | };
|
---|
40 |
|
---|
41 | if ($window.google && $window.google.maps && $window.InfoBox) {
|
---|
42 | utils.safeApply(scope, function () {
|
---|
43 | initGoogleMaps();
|
---|
44 | });
|
---|
45 | } else {
|
---|
46 | initGoogleMapsAsync();
|
---|
47 | }
|
---|
48 |
|
---|
49 | function initGoogleMapsAsync() {
|
---|
50 | $.when(LoadGoogleMapsWithPromise())
|
---|
51 | .then(function () {
|
---|
52 | return $.ajax({ url: "/scripts/vendor/infobox.min.js", dataType: "script", cache: true });
|
---|
53 | })
|
---|
54 | .then(function () {
|
---|
55 | utils.safeApply(scope, function () {
|
---|
56 | initGoogleMaps();
|
---|
57 | });
|
---|
58 | });
|
---|
59 | };
|
---|
60 |
|
---|
61 | function initGoogleMaps() {
|
---|
62 | if ((!$window.google && !$window.google.maps) || !window.InfoBox) {
|
---|
63 | throw "Google maps or InfoBox failed to load";
|
---|
64 | }
|
---|
65 |
|
---|
66 | scope.mapOptions = scope.$eval('{' + attrs.mapOptions + '}');
|
---|
67 | scope.mapOptions.mapId = attrs.id;
|
---|
68 |
|
---|
69 | if (scope.mapOptions.directionsId) {
|
---|
70 | setDirectionsCallbacks();
|
---|
71 | }
|
---|
72 |
|
---|
73 | // Handle user location callback
|
---|
74 | if (angular.isDefined(scope.googleMapModule)) {
|
---|
75 | scope.mapOptions.userLocationSetCallback = function (userLocation) {
|
---|
76 | utils.safeApply(scope, function (){
|
---|
77 | scope.googleMapModule.userLocation = userLocation;
|
---|
78 | });
|
---|
79 | };
|
---|
80 |
|
---|
81 | scope.mapOptions.zoomLevelSetCallback = function (zoomLevel, mapCenter) {
|
---|
82 | utils.safeApply(scope, function () {
|
---|
83 | scope.googleMapModule.currentZoomLevel = zoomLevel;
|
---|
84 | scope.googleMapModule.curMapCenter = mapCenter;
|
---|
85 | scope.googleMapModule.isAutoSearch = true;
|
---|
86 | });
|
---|
87 | };
|
---|
88 |
|
---|
89 | scope.mapOptions.mapCenterSetCallback = function (zoomLevel, mapCenter) {
|
---|
90 | utils.safeApply(scope, function () {
|
---|
91 | scope.googleMapModule.currentZoomLevel = zoomLevel;
|
---|
92 | scope.googleMapModule.curMapCenter = mapCenter;
|
---|
93 | scope.googleMapModule.isAutoSearch = true;
|
---|
94 | });
|
---|
95 | };
|
---|
96 | }
|
---|
97 | // Add google map to scope.googleMap namespace
|
---|
98 | GoogleMap.call(scope.googleMapModule, scope.mapOptions);
|
---|
99 | }
|
---|
100 |
|
---|
101 | function setDirectionsCallbacks() {
|
---|
102 | var $mapDirections = $('#' + scope.mapOptions.directionsId);
|
---|
103 | var $mapDirectionsContainer = $mapDirections.parent();
|
---|
104 |
|
---|
105 | scope.mapOptions.directionsOnSetCallback = function (directionsObject) {
|
---|
106 | scope.$apply(function () {
|
---|
107 | scope.googleMapModule.directions = directionsObject;
|
---|
108 | });
|
---|
109 |
|
---|
110 | var directionsHtml = getDirectionsHtml(directionsObject);
|
---|
111 |
|
---|
112 | $mapDirections.slideDown(200).promise().done(function () {
|
---|
113 | $mapDirections.html(directionsHtml);
|
---|
114 | reinitialiseJscroll($mapDirectionsContainer);
|
---|
115 | });
|
---|
116 | };
|
---|
117 |
|
---|
118 | scope.mapOptions.directionsOnUpdateCallback = function (directionsObject) {
|
---|
119 | scope.$apply(function () {
|
---|
120 | scope.googleMapModule.directions = directionsObject;
|
---|
121 | });
|
---|
122 |
|
---|
123 | var directionsHtml = getDirectionsHtml(directionsObject);
|
---|
124 | $mapDirections.html(directionsHtml);
|
---|
125 | reinitialiseJscroll($mapDirectionsContainer);
|
---|
126 | };
|
---|
127 |
|
---|
128 | scope.mapOptions.directionsOnCloseCallback = function (directionsObject) {
|
---|
129 | $mapDirections.slideUp(200).html("");
|
---|
130 | };
|
---|
131 |
|
---|
132 | var widowResizedTimer;
|
---|
133 | $(window).resize(function () {
|
---|
134 | // Wait 500ms after window has stopped resizing
|
---|
135 | clearTimeout(widowResizedTimer);
|
---|
136 | widowResizedTimer = $timeout(function () {
|
---|
137 | reinitialiseJscroll($mapDirectionsContainer);
|
---|
138 | }, 500);
|
---|
139 | });
|
---|
140 |
|
---|
141 | function getDirectionsHtml(directionsObject) {
|
---|
142 | var directionsHtml = '';
|
---|
143 | directionsHtml += "<p><strong>From</strong>: " + directionsObject.start_address + "</p>";
|
---|
144 | directionsHtml += "<p><strong>To</strong>: " + directionsObject.end_address + "</p>";
|
---|
145 | directionsHtml += "<p><strong>Distance</strong>: " + directionsObject.distance.text + " (about " + directionsObject.duration.text + ").</p>";
|
---|
146 | directionsHtml += "<hr>";
|
---|
147 |
|
---|
148 | angular.forEach(directionsObject.steps, function (item) {
|
---|
149 | directionsHtml += '<p>' + item.instructions + '</p>';
|
---|
150 | });
|
---|
151 |
|
---|
152 | return directionsHtml;
|
---|
153 | }
|
---|
154 |
|
---|
155 | }
|
---|
156 | }
|
---|
157 | }])
|
---|
158 | // data-jscroll-callback
|
---|
159 | .directive('jscrollCallback', ['$timeout', '$window', function ($timeout, $window) {
|
---|
160 | return {
|
---|
161 | restrict: 'A',
|
---|
162 | link: function (scope, element, attrs) {
|
---|
163 | scope.$watch(attrs.jscrollCallback, function (oldVal, newVal) {
|
---|
164 | var keys = scope.$eval(attrs.jscrollCallback);
|
---|
165 | if (keys.length) {
|
---|
166 | reinitialiseJscroll(element);
|
---|
167 | }
|
---|
168 | });
|
---|
169 |
|
---|
170 | var widowResized;
|
---|
171 | $(window).resize(function () {
|
---|
172 | // Wait 200ms after window has stopped resizing
|
---|
173 | clearTimeout(widowResized);
|
---|
174 | widowResized = $timeout(function () {
|
---|
175 | reinitialiseJscroll(element);
|
---|
176 | }, 200);
|
---|
177 | });
|
---|
178 | }
|
---|
179 | };
|
---|
180 | }]);
|
---|
181 |
|
---|
182 | })(angular, window.jQuery || angular.element); |
---|