ngmap
Version:
The Simplest AngularJS Google Maps V3 Directive
223 lines • 15.7 kB
HTML
<html>
<head>
<meta charset="utf-8">
<base href="../">
<title>JSDoc: source : custom-marker.js</title>
<link href="css/prettify-tomorrow.css" type="text/css" rel="stylesheet">
<link href="css/site.css" type="text/css" rel="stylesheet">
</head>
<body ng-app="">
<nav id="toc">
<input placeholder="Filter" id="filter-input" class="col12 block field" type="text">
<div class="nav-wrapper">
<h2><a href="index.html">Index</a></h2>
<ul class="module">
<!-- undefined -->
<h2 class="module">
<a chref="" ng-click="moduleundefined = !moduleundefined">
module: undefined
</a>
<i ng-cloak="" ng-show="moduleundefined">+</i>
</h2>
<li id="undefined" ng-hide="moduleundefined">
<ul class="group">
<h2>
<a href="" ng-click="undefinedservice = !undefinedservice">
service
</a>
<i ng-cloak="" ng-show="undefinedservice">+</i>
</h2>
<ul ng-hide="undefinedservice">
<li>
<a href="Attr2MapOptions.html">Attr2MapOptions</a>
</li><li>
<a href="GeoCoder.html">GeoCoder</a>
</li><li>
<a href="GoogleMapsApi.html">GoogleMapsApi</a>
</li><li>
<a href="NavigatorGeolocation.html">NavigatorGeolocation</a>
</li><li>
<a href="StreetView.html">StreetView</a>
</li>
</ul>
</ul><ul class="group">
<h2>
<a href="" ng-click="undefineddirective = !undefineddirective">
directive
</a>
<i ng-cloak="" ng-show="undefineddirective">+</i>
</h2>
<ul ng-hide="undefineddirective">
<li>
<a href="bicycling-layer.html">bicycling-layer</a>
</li><li>
<a href="custom-control.html">custom-control</a>
</li><li>
<a href="directions.html">directions</a>
</li><li>
<a href="drawing-manager.html">drawing-manager</a>
</li><li>
<a href="dynamic-maps-engine-layer.html">dynamic-maps-engine-layer</a>
</li><li>
<a href="fusion-tables-layer.html">fusion-tables-layer</a>
</li><li>
<a href="heatmap-layer.html">heatmap-layer</a>
</li><li>
<a href="info-window.html">info-window</a>
</li><li>
<a href="kml-layer.html">kml-layer</a>
</li><li>
<a href="map-data.html">map-data</a>
</li><li>
<a href="map-lazy-load.html">map-lazy-load</a>
</li><li>
<a href="map-type.html">map-type</a>
</li><li>
<a href="maps-engine-layer.html">maps-engine-layer</a>
</li><li>
<a href="marker.html">marker</a>
</li><li>
<a href="overlay-map-type.html">overlay-map-type</a>
</li><li>
<a href="places-auto-complete.html">places-auto-complete</a>
</li><li>
<a href="shape.html">shape</a>
</li><li>
<a href="streetview-panorama.html">streetview-panorama</a>
</li><li>
<a href="traffic-layer.html">traffic-layer</a>
</li><li>
<a href="transit-layer.html">transit-layer</a>
</li>
</ul>
</ul><ul class="group">
<h2>
<a href="" ng-click="undefinedprovider = !undefinedprovider">
provider
</a>
<i ng-cloak="" ng-show="undefinedprovider">+</i>
</h2>
<ul ng-hide="undefinedprovider">
<li>
<a href="NgMap.html">NgMap</a>
</li>
</ul>
</ul><ul class="group">
<h2>
<a href="" ng-click="undefinedfactory = !undefinedfactory">
factory
</a>
<i ng-cloak="" ng-show="undefinedfactory">+</i>
</h2>
<ul ng-hide="undefinedfactory">
<li>
<a href="NgMapPool.html">NgMapPool</a>
</li>
</ul>
</ul>
</li>
</ul><ul class="module">
<!-- ngmap -->
<h2 class="module">
<a chref="" ng-click="modulengmap = !modulengmap">
module: ngmap
</a>
<i ng-cloak="" ng-show="modulengmap">+</i>
</h2>
<li id="ngmap" ng-hide="modulengmap">
<ul class="group">
<h2>
<a href="" ng-click="ngmapdirective = !ngmapdirective">
directive
</a>
<i ng-cloak="" ng-show="ngmapdirective">+</i>
</h2>
<ul ng-hide="ngmapdirective">
<li>
<a href="ngmap.custom-marker.html">custom-marker</a>
</li>
</ul>
</ul>
</li>
</ul><ul class="module">
<!-- ng_ap -->
<h2 class="module">
<a chref="" ng-click="moduleng_ap = !moduleng_ap">
module: ngMap
</a>
<i ng-cloak="" ng-show="moduleng_ap">+</i>
</h2>
<li id="ngMap" ng-hide="moduleng_ap">
<ul class="group">
<h2>
<a href="" ng-click="ng_apdirective = !ng_apdirective">
directive
</a>
<i ng-cloak="" ng-show="ng_apdirective">+</i>
</h2>
<ul ng-hide="ng_apdirective">
<li>
<a href="ngMap.ng-map.html">ng-map</a>
</li>
</ul>
</ul>
</li>
</ul>
</div>
</nav>
<div id="content" class="page-wrap">
<h1 class="title">
source : custom-marker.js
</h1>
<div id="main" class="big-container">
<!-- source code html -->
<article>
<pre class="prettyprint source linenums"><code>/**
* @ngdoc directive
* @memberof ngmap
* @name custom-marker
* @param Attr2Options {service} convert html attribute to Google map api options
* @param $timeout {service} AngularJS $timeout
* @description
* Marker with html
* Requires: map directive
* Restrict To: Element
*
* @attr {String} position required, position on map
* @attr {Number} z-index optional
* @attr {Boolean} visible optional
* @example
*
* Example:
* <map center="41.850033,-87.6500523" zoom="3">
* <custom-marker position="41.850033,-87.6500523">
* <div>
* <b>Home</b>
* </div>
* </custom-marker>
* </map>
*
*/
/* global document */
(function() {
'use strict';
var parser, $timeout, $compile, NgMap;
var supportedTransform = (function getSupportedTransform() {
var prefixes = 'transform WebkitTransform MozTransform OTransform msTransform'.split(' ');
var div = document.createElement('div');
for(var i = 0; i < prefixes.length; i++) {
if(div && div.style[prefixes[i]] !== undefined) {
return prefixes[i];
}
}
return false;
})();
var CustomMarker = function(options) {
options = options || {};
this.el = document.createElement('div');
this.el.style.display = 'block';
this.el.style.visibility = "hidden";
this.visible = true;
for (var key in options) { /* jshint ignore:line */
this[key] = options[key];
}
};
var setCustomMarker = function() {
CustomMarker.prototype = new google.maps.OverlayView();
CustomMarker.prototype.setContent = function(html, scope) {
this.el.innerHTML = html;
this.el.style.position = 'absolute';
this.el.style.top = 0;
this.el.style.left = 0;
if (scope) {
$compile(angular.element(this.el).contents())(scope);
}
};
CustomMarker.prototype.getDraggable = function() {
return this.draggable;
};
CustomMarker.prototype.setDraggable = function(draggable) {
this.draggable = draggable;
};
CustomMarker.prototype.getPosition = function() {
return this.position;
};
CustomMarker.prototype.setPosition = function(position) {
position && (this.position = position); /* jshint ignore:line */
var _this = this;
if (this.getProjection() && typeof this.position.lng == 'function') {
console.log(_this.getProjection());
var setPosition = function() {
if (!_this.getProjection()) { return; }
var posPixel = _this.getProjection().fromLatLngToDivPixel(_this.position);
var x = Math.round(posPixel.x - (_this.el.offsetWidth/2));
var y = Math.round(posPixel.y - _this.el.offsetHeight - 10); // 10px for anchor
if (supportedTransform) {
_this.el.style[supportedTransform] = "translate(" + x + "px, " + y + "px)";
} else {
_this.el.style.left = x + "px";
_this.el.style.top = y + "px";
}
_this.el.style.visibility = "visible";
};
if (_this.el.offsetWidth && _this.el.offsetHeight) {
setPosition();
} else {
//delayed left/top calculation when width/height are not set instantly
$timeout(setPosition, 300);
}
}
};
CustomMarker.prototype.setZIndex = function(zIndex) {
if (zIndex === undefined) return;
(this.zIndex !== zIndex) && (this.zIndex = zIndex); /* jshint ignore:line */
(this.el.style.zIndex !== this.zIndex) && (this.el.style.zIndex = this.zIndex);
};
CustomMarker.prototype.getVisible = function() {
return this.visible;
};
CustomMarker.prototype.setVisible = function(visible) {
if (this.el.style.display === 'none' && visible)
{
this.el.style.display = 'block';
} else if (this.el.style.display !== 'none' && !visible) {
this.el.style.display = 'none';
}
this.visible = visible;
};
CustomMarker.prototype.addClass = function(className) {
var classNames = this.el.className.trim().split(' ');
(classNames.indexOf(className) == -1) && classNames.push(className); /* jshint ignore:line */
this.el.className = classNames.join(' ');
};
CustomMarker.prototype.removeClass = function(className) {
var classNames = this.el.className.split(' ');
var index = classNames.indexOf(className);
(index > -1) && classNames.splice(index, 1); /* jshint ignore:line */
this.el.className = classNames.join(' ');
};
CustomMarker.prototype.onAdd = function() {
this.getPanes().overlayMouseTarget.appendChild(this.el);
};
CustomMarker.prototype.draw = function() {
this.setPosition();
this.setZIndex(this.zIndex);
this.setVisible(this.visible);
};
CustomMarker.prototype.onRemove = function() {
this.el.parentNode.removeChild(this.el);
//this.el = null;
};
};
var linkFunc = function(orgHtml, varsToWatch) {
//console.log('orgHtml', orgHtml, 'varsToWatch', varsToWatch);
return function(scope, element, attrs, mapController) {
mapController = mapController[0]||mapController[1];
var orgAttrs = parser.orgAttributes(element);
var filtered = parser.filter(attrs);
var options = parser.getOptions(filtered, {scope: scope});
var events = parser.getEvents(scope, filtered);
/**
* build a custom marker element
*/
element[0].style.display = 'none';
console.log("custom-marker options", options);
var customMarker = new CustomMarker(options);
// Do we really need a timeout with $scope.$apply() here?
setTimeout(function() { //apply contents, class, and location after it is compiled
scope.$watch('[' + varsToWatch.join(',') + ']', function(newVal, oldVal) {
customMarker.setContent(orgHtml, scope);
}, true);
customMarker.setContent(element[0].innerHTML, scope);
var classNames =
(element[0].firstElementChild) && (element[0].firstElementChild.className || '');
customMarker.class && (classNames += " " + customMarker.class);
customMarker.addClass('custom-marker');
classNames && customMarker.addClass(classNames);
console.log('customMarker', customMarker, 'classNames', classNames);
if (!(options.position instanceof google.maps.LatLng)) {
NgMap.getGeoLocation(options.position).then(
function(latlng) {
customMarker.setPosition(latlng);
}
);
}
});
console.log("custom-marker events", events);
for (var eventName in events) { /* jshint ignore:line */
google.maps.event.addDomListener(
customMarker.el, eventName, events[eventName]);
}
mapController.addObject('customMarkers', customMarker);
//set observers
mapController.observeAttrSetObj(orgAttrs, attrs, customMarker);
element.bind('$destroy', function() {
//Is it required to remove event listeners when DOM is removed?
mapController.deleteObject('customMarkers', customMarker);
});
}; // linkFunc
};
var customMarkerDirective = function(
_$timeout_, _$compile_, $interpolate, Attr2MapOptions, _NgMap_, escapeRegExp
) {
parser = Attr2MapOptions;
$timeout = _$timeout_;
$compile = _$compile_;
NgMap = _NgMap_;
var exprStartSymbol = $interpolate.startSymbol();
var exprEndSymbol = $interpolate.endSymbol();
var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '([^' + exprEndSymbol.substring(0, 1) + ']+)' + escapeRegExp(exprEndSymbol), 'g');
return {
restrict: 'E',
require: ['?^map','?^ngMap'],
compile: function(element) {
console.log('el', element);
setCustomMarker();
element[0].style.display ='none';
var orgHtml = element.html();
var matches = orgHtml.match(exprRegExp);
var varsToWatch = [];
//filter out that contains '::', 'this.'
(matches || []).forEach(function(match) {
var toWatch = match.replace(exprStartSymbol,'').replace(exprEndSymbol,'');
if (match.indexOf('::') == -1 &&
match.indexOf('this.') == -1 &&
varsToWatch.indexOf(toWatch) == -1) {
varsToWatch.push(match.replace(exprStartSymbol,'').replace(exprEndSymbol,''));
}
});
return linkFunc(orgHtml, varsToWatch);
}
}; // return
};// function
customMarkerDirective.$inject =
['$timeout', '$compile', '$interpolate', 'Attr2MapOptions', 'NgMap', 'escapeRegexpFilter'];
angular.module('ngMap').directive('customMarker', customMarkerDirective);
})();
</code></pre>
</article>
<!-- index.html -->
<!-- class files -->
</div>
<footer style="clear:both">
Documentation generated by
<a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.2</a>
using
<a href="https://github.com/allenhwkim/angular-jsdoc">Angular-JSDoc template</a>
</footer>
</div>
<script src="js/prettify.js"></script>
<script src="js/angular.min.js"></script>
<script src="js/site.js"></script>
<!--%= prettyJson %-->
<script>
prettyPrint();
var lineNo = window.location.hash.match(/#line([0-9]+)$/);
lineNo && document.querySelector("ol li:nth-child("+(lineNo[1])+")").scrollIntoView();
</script>
</body>
</html>