177 lines
6.0 KiB
JavaScript
Executable File
177 lines
6.0 KiB
JavaScript
Executable File
/*jshint -W030*/
|
|
/**
|
|
* @ngdoc directive
|
|
* @name info-window
|
|
* @requires Attr2Options
|
|
* @requires $compile
|
|
* @description
|
|
* Defines infoWindow and provides compile method
|
|
*
|
|
* Requires: map directive
|
|
*
|
|
* Restrict To: Element
|
|
*
|
|
* @param {Boolean} visible Indicates to show it when map is initialized
|
|
* @param {Boolean} visible-on-marker Indicates to show it on a marker when map is initialized
|
|
* @param {String} <InfoWindowOption> Any InfoWindow options,
|
|
* https://developers.google.com/maps/documentation/javascript/reference?csw=1#InfoWindowOptions
|
|
* @param {String} <InfoWindowEvent> Any InfoWindow events, https://developers.google.com/maps/documentation/javascript/reference
|
|
* @example
|
|
* Usage:
|
|
* <map MAP_ATTRIBUTES>
|
|
* <info-window id="foo" ANY_OPTIONS ANY_EVENTS"></info-window>
|
|
* </map>
|
|
*
|
|
* Example:
|
|
* <map center="41.850033,-87.6500523" zoom="3">
|
|
* <info-window id="1" position="41.850033,-87.6500523" >
|
|
* <div ng-non-bindable>
|
|
* Chicago, IL<br/>
|
|
* LatLng: {{chicago.lat()}}, {{chicago.lng()}}, <br/>
|
|
* World Coordinate: {{worldCoordinate.x}}, {{worldCoordinate.y}}, <br/>
|
|
* Pixel Coordinate: {{pixelCoordinate.x}}, {{pixelCoordinate.y}}, <br/>
|
|
* Tile Coordinate: {{tileCoordinate.x}}, {{tileCoordinate.y}} at Zoom Level {{map.getZoom()}}
|
|
* </div>
|
|
* </info-window>
|
|
* </map>
|
|
*/
|
|
ngMap.directive('infoWindow', ['Attr2Options', '$compile', '$timeout', function(Attr2Options, $compile, $timeout) {
|
|
var parser = Attr2Options;
|
|
|
|
var getInfoWindow = function(options, events, element) {
|
|
var infoWindow;
|
|
|
|
/**
|
|
* set options
|
|
*/
|
|
if (options.position &&
|
|
!(options.position instanceof google.maps.LatLng)) {
|
|
var address = options.position;
|
|
delete options.position;
|
|
infoWindow = new google.maps.InfoWindow(options);
|
|
var callback = function() {
|
|
infoWindow.open(infoWindow.map);
|
|
}
|
|
parser.setDelayedGeoLocation(infoWindow, 'setPosition', address, {callback: callback});
|
|
} else {
|
|
infoWindow = new google.maps.InfoWindow(options);
|
|
}
|
|
|
|
/**
|
|
* set events
|
|
*/
|
|
if (Object.keys(events).length > 0) {
|
|
console.log("infoWindow events", events);
|
|
}
|
|
for (var eventName in events) {
|
|
if (eventName) {
|
|
google.maps.event.addListener(infoWindow, eventName, events[eventName]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* set template ane template-relate functions
|
|
* it must have a container element with ng-non-bindable
|
|
*/
|
|
var template = element.html().trim();
|
|
if (angular.element(template).length != 1) {
|
|
throw "info-window working as a template must have a container";
|
|
}
|
|
infoWindow.__template = template.replace(/\s?ng-non-bindable[='"]+/,"");
|
|
|
|
infoWindow.__compile = function(scope) {
|
|
var el = $compile(infoWindow.__template)(scope);
|
|
scope.$apply();
|
|
infoWindow.setContent(el[0]);
|
|
};
|
|
|
|
infoWindow.__eval = function(event) {
|
|
var template = infoWindow.__template;
|
|
var _this = this;
|
|
template = template.replace(/{{(event|this)[^;\}]+}}/g, function(match) {
|
|
var expression = match.replace(/[{}]/g, "").replace("this.", "_this.");
|
|
return eval(expression);
|
|
});
|
|
return template;
|
|
};
|
|
|
|
return infoWindow;
|
|
};
|
|
|
|
return {
|
|
restrict: 'E',
|
|
require: '^map',
|
|
link: function(scope, element, attrs, mapController) {
|
|
element.css('display','none');
|
|
var orgAttrs = parser.orgAttributes(element);
|
|
var filtered = parser.filter(attrs);
|
|
var options = parser.getOptions(filtered, scope);
|
|
var events = parser.getEvents(scope, filtered);
|
|
console.log('infoWindow', 'options', options, 'events', events);
|
|
|
|
var infoWindow = getInfoWindow(options, events, element);
|
|
|
|
mapController.addObject('infoWindows', infoWindow);
|
|
parser.observeAttrSetObj(orgAttrs, attrs, infoWindow); /* observers */
|
|
|
|
// show InfoWindow when initialized
|
|
if (infoWindow.visible) {
|
|
//if (!infoWindow.position) { throw "Invalid position"; }
|
|
scope.$on('mapInitialized', function(evt, map) {
|
|
$timeout(function() {
|
|
infoWindow.__template = infoWindow.__eval.apply(this, [evt]);
|
|
infoWindow.__compile(scope);
|
|
infoWindow.map = map;
|
|
infoWindow.position && infoWindow.open(map);
|
|
});
|
|
});
|
|
}
|
|
|
|
// show InfoWindow on a marker when initialized
|
|
if (infoWindow.visibleOnMarker) {
|
|
scope.$on('mapInitialized', function(evt, map) {
|
|
$timeout(function() {
|
|
var markerId = infoWindow.visibleOnMarker;
|
|
var marker = map.markers[markerId];
|
|
if (!marker) throw "Invalid marker id";
|
|
infoWindow.__template = infoWindow.__eval.apply(this, [evt]);
|
|
infoWindow.__compile(scope);
|
|
infoWindow.open(map, marker);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* provide showInfoWindow method to scope
|
|
*/
|
|
scope.showInfoWindow = scope.showInfoWindow ||
|
|
function(event, id, anchor) {
|
|
var infoWindow = mapController.map.infoWindows[id],
|
|
tempTemplate = infoWindow.__template; // set template in a temporary variable
|
|
infoWindow.__template = infoWindow.__eval.apply(this, [event]);
|
|
infoWindow.__compile(scope);
|
|
if (anchor) {
|
|
infoWindow.open(mapController.map, anchor);
|
|
} else if (this.getPosition) {
|
|
infoWindow.open(mapController.map, this);
|
|
} else {
|
|
infoWindow.open(mapController.map);
|
|
}
|
|
infoWindow.__template = tempTemplate; // reset template to the object
|
|
};
|
|
|
|
/**
|
|
* provide hideInfoWindow method to scope
|
|
*/
|
|
scope.hideInfoWindow = scope.hideInfoWindow ||
|
|
function(event, id, anchor) {
|
|
var infoWindow = mapController.map.infoWindows[id];
|
|
infoWindow.__template = infoWindow.__eval.apply(this, [event]);
|
|
infoWindow.__compile(scope);
|
|
infoWindow.close();
|
|
};
|
|
|
|
} //link
|
|
}; // return
|
|
}]);// function
|