ng-click inside ui-gmap-windows not working - javascript

ng-click inside ui-gmap-windows not working...
Here is codepen link http://codepen.io/aoakeson/pen/ZYLJeyhttp://codepen.io/aoakeson/pen/ZYLJey
Any suggestion as how this issue is to be solved....
Here is html code:
<ui-gmap-google-map center='map.center' zoom='map.zoom' draggable="true">
<ui-gmap-markers models="randomMarkers" coords="'self'" icon="'icon'" click="'onClick'">
<ui-gmap-windows show="show" ng-cloak>
<div class="lp_tuxtla" >
<div >
<a ng-click="nextpage()">click here</a>
<h3 ng-non-bindable >{{title}}</h3>
<h4 ng-non-bindable>{{loc}}</h4>
</div>
<span class="right_arw"></span>
<span class="down_arw"></span>
</div>
<!-- <div ng-non-bindable >{{title}}</div>-->
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
Here javascript code:
$scope.map = {center: {latitude: 40.1451, longitude: -99.6680 }, zoom: 4, bounds: {}};
$scope.options = {scrollwheel: false};
var createRandomMarker = function (i, bounds, idKey) {
var lat_min = bounds.southwest.latitude,
lat_range = bounds.northeast.latitude - lat_min,
lng_min = bounds.southwest.longitude,
lng_range = bounds.northeast.longitude - lng_min;
if (idKey == null) {
idKey = "id";
}
var latitude = lat_min + (Math.random() * lat_range);
var longitude = lng_min + (Math.random() * lng_range);
var ret = {
latitude: latitude,
longitude: longitude,
title: 'm' + i,
show: false
};
ret.onClick = function() {
console.log("Clicked!");
ret.show = !ret.show;
};
ret[idKey] = i;
return ret;
};
$scope.randomMarkers = [];
// Get the bounds from the map once it's loaded
$scope.$watch(function() { return $scope.map.bounds; }, function(nv, ov) {
// Only need to regenerate once
if (!ov.southwest && nv.southwest) {
var markers = [];
for (var i = 0; i < 50; i++) {
markers.push(createRandomMarker(i, $scope.map.bounds))
}
$scope.randomMarkers = markers;
}
}, true);

Somehow, its not able to reach the 'windowClicked' method in the hierarchy.
Create the method on rootScope and use it in the tempalte.
In Controller
$scope.$root.windowClicked = function () {alert('here')}
In Markup
<a ng-click="$root.windowClicked()">test</a>
Here is the updated pen. http://codepen.io/anon/pen/qEKjjb

First way
You can use your $scope declared variables in ng-click using $parent:
<button ng-click="$parent.nextPage()">next</button>
Here is a working plunker.
Second way
You can assign a controller to the div containing the window.
<div ng-controller="mainCtrl">
<button ng-click="nextPage()">next</button>
</div>
Here is another working plunker
Credits
People in Github issue

Most likely it is the same issue that has been discussed in this thread.
Apparently it occurs since nextpage event declared in controller scope is not accessible from the ui-gmap-windows child scope.
The following solution worked for me:
First we need to introduce an additional controller:
appMaps.controller('infoWindowCtrl', function($scope) {
$scope.showInfo = function() {
console.log('Button clicked!');
}
});
and then specify the following layout:
<ui-gmap-windows show="show">
<div ng-controller="infoWindowCtrl">
<span ng-non-bindable>{{title}}</span>
<button ng-click="showInfo()">Show info</button>
</div>
</ui-gmap-windows>
Working example
var appMaps = angular.module('appMaps', ['uiGmapgoogle-maps']);
appMaps.controller('mainCtrl', function($scope,uiGmapIsReady) {
$scope.map = { center: { latitude: 40.1451, longitude: -99.6680 }, zoom: 4, bounds: {} };
$scope.options = { scrollwheel: false };
var getRandomLat = function() {
return Math.random() * (90.0 + 90.0) - 90.0;
};
var getRandomLng = function () {
return Math.random() * (180.0 + 180.0) - 180.0;
};
var createRandomMarker = function(i) {
var ret = {
latitude: getRandomLat(),
longitude: getRandomLng(),
title: 'm' + i,
show: false,
id: i
};
return ret;
};
$scope.onClick = function(marker, eventName, model) {
logInfo("Marker clicked!");
model.show = !model.show;
};
$scope.markers = [];
for (var i = 0; i < 200; i++) {
$scope.markers.push(createRandomMarker(i));
}
});
appMaps.controller('infoWindowCtrl', function($scope) {
$scope.showInfo = function() {
logInfo('Button clicked!');
}
});
function logInfo(message){
console.log(message);
document.getElementById('output').innerHTML += message;
}
html, body, #map_canvas {
height: 100%;
width: 100%;
margin: 0px;
}
#map_canvas {
position: relative;
}
.angular-google-map-container {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
<script src="https://code.angularjs.org/1.3.14/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src="http://rawgit.com/angular-ui/angular-google-maps/2.0.X/dist/angular-google-maps.js"></script>
<div ng-app="appMaps" id="map_canvas" ng-controller="mainCtrl">
<ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="options" bounds="map.bounds">
<ui-gmap-markers models="markers" coords="'self'" icon="'icon'" click="onClick">
<ui-gmap-windows show="show">
<div ng-controller="infoWindowCtrl">
<span ng-non-bindable>{{title}}</span>
<button ng-click="showInfo()">Show info</button>
</div>
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</div>
<pre id="output"></pre>
Plunker

Related

Change mapbox on google maps

I am trying swich map box to google maps in some map app.
This shows polyline on map, but i have one problem.
Here is my code :
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://portal.company.io/theme/plugins/moment.js"></script>
<script src="https://portal.company.io/Scripts/googlemap/mapstyle.js"></script>
<script src="https://portal.company.io/Scripts/googlemap/markerclusterer.js"></script>
<script type="text/javascript">
(function(t,e){"function"==typeof define&&define.amd?define(["leaflet"],t):"object"==typeof exports&&(module.exports=t(require("leaflet"))),e!==void 0&&e.L&&(e.LeafletLabel=t(L))})(function(t){t.labelVersion="0.2.4";var e=t.Class.extend({includes:t.Mixin.Events,options:{className:"",clickable:!1,direction:"right",noHide:!1,offset:[12,-15],opacity:1,zoomAnimation:!0},initialize:function(e,i){t.setOptions(this,e),this._source=i,this._animated=t.Browser.any3d&&this.options.zoomAnimation,this._isOpen=!1},onAdd:function(e){this._map=e,this._pane=this.options.pane?e._panes[this.options.pane]:this._source instanceof t.Marker?e._panes.markerPane:e._panes.popupPane,this._container||this._initLayout(),this._pane.appendChild(this._container),this._initInteraction(),this._update(),this.setOpacity(this.options.opacity),e.on("moveend",this._onMoveEnd,this).on("viewreset",this._onViewReset,this),this._animated&&e.on("zoomanim",this._zoomAnimation,this),t.Browser.touch&&!this.options.noHide&&(t.DomEvent.on(this._container,"click",this.close,this),e.on("click",this.close,this))},onRemove:function(t){this._pane.removeChild(this._container),t.off({zoomanim:this._zoomAnimation,moveend:this._onMoveEnd,viewreset:this._onViewReset},this),this._removeInteraction(),this._map=null},setLatLng:function(e){return this._latlng=t.latLng(e),this._map&&this._updatePosition(),this},setContent:function(t){return this._previousContent=this._content,this._content=t,this._updateContent(),this},close:function(){var e=this._map;e&&(t.Browser.touch&&!this.options.noHide&&(t.DomEvent.off(this._container,"click",this.close),e.off("click",this.close,this)),e.removeLayer(this))},updateZIndex:function(t){this._zIndex=t,this._container&&this._zIndex&&(this._container.style.zIndex=t)},setOpacity:function(e){this.options.opacity=e,this._container&&t.DomUtil.setOpacity(this._container,e)},_initLayout:function(){this._container=t.DomUtil.create("div","leaflet-label "+this.options.className+" leaflet-zoom-animated"),this.updateZIndex(this._zIndex)},_update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updatePosition(),this._container.style.visibility="")},_updateContent:function(){this._content&&this._map&&this._prevContent!==this._content&&"string"==typeof this._content&&(this._container.innerHTML=this._content,this._prevContent=this._content,this._labelWidth=this._container.offsetWidth)},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},_setPosition:function(e){var i=this._map,n=this._container,o=i.latLngToContainerPoint(i.getCenter()),s=i.layerPointToContainerPoint(e),a=this.options.direction,l=this._labelWidth,h=t.point(this.options.offset);"right"===a||"auto"===a&&s.x<o.x?(t.DomUtil.addClass(n,"leaflet-label-right"),t.DomUtil.removeClass(n,"leaflet-label-left"),e=e.add(h)):(t.DomUtil.addClass(n,"leaflet-label-left"),t.DomUtil.removeClass(n,"leaflet-label-right"),e=e.add(t.point(-h.x-l,h.y))),t.DomUtil.setPosition(n,e)},_zoomAnimation:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPosition(e)},_onMoveEnd:function(){this._animated&&"auto"!==this.options.direction||this._updatePosition()},_onViewReset:function(t){t&&t.hard&&this._update()},_initInteraction:function(){if(this.options.clickable){var e=this._container,i=["dblclick","mousedown","mouseover","mouseout","contextmenu"];t.DomUtil.addClass(e,"leaflet-clickable"),t.DomEvent.on(e,"click",this._onMouseClick,this);for(var n=0;i.length>n;n++)t.DomEvent.on(e,i[n],this._fireMouseEvent,this)}},_removeInteraction:function(){if(this.options.clickable){var e=this._container,i=["dblclick","mousedown","mouseover","mouseout","contextmenu"];t.DomUtil.removeClass(e,"leaflet-clickable"),t.DomEvent.off(e,"click",this._onMouseClick,this);for(var n=0;i.length>n;n++)t.DomEvent.off(e,i[n],this._fireMouseEvent,this)}},_onMouseClick:function(e){this.hasEventListeners(e.type)&&t.DomEvent.stopPropagation(e),this.fire(e.type,{originalEvent:e})},_fireMouseEvent:function(e){this.fire(e.type,{originalEvent:e}),"contextmenu"===e.type&&this.hasEventListeners(e.type)&&t.DomEvent.preventDefault(e),"mousedown"!==e.type?t.DomEvent.stopPropagation(e):t.DomEvent.preventDefault(e)}});return t.BaseMarkerMethods={showLabel:function(){return this.label&&this._map&&(this.label.setLatLng(this._latlng),this._map.showLabel(this.label)),this},hideLabel:function(){return this.label&&this.label.close(),this},setLabelNoHide:function(t){this._labelNoHide!==t&&(this._labelNoHide=t,t?(this._removeLabelRevealHandlers(),this.showLabel()):(this._addLabelRevealHandlers(),this.hideLabel()))},bindLabel:function(i,n){var o=this.options.icon?this.options.icon.options.labelAnchor:this.options.labelAnchor,s=t.point(o)||t.point(0,0);return s=s.add(e.prototype.options.offset),n&&n.offset&&(s=s.add(n.offset)),n=t.Util.extend({offset:s},n),this._labelNoHide=n.noHide,this.label||(this._labelNoHide||this._addLabelRevealHandlers(),this.on("remove",this.hideLabel,this).on("move",this._moveLabel,this).on("add",this._onMarkerAdd,this),this._hasLabelHandlers=!0),this.label=new e(n,this).setContent(i),this},unbindLabel:function(){return this.label&&(this.hideLabel(),this.label=null,this._hasLabelHandlers&&(this._labelNoHide||this._removeLabelRevealHandlers(),this.off("remove",this.hideLabel,this).off("move",this._moveLabel,this).off("add",this._onMarkerAdd,this)),this._hasLabelHandlers=!1),this},updateLabelContent:function(t){this.label&&this.label.setContent(t)},getLabel:function(){return this.label},_onMarkerAdd:function(){this._labelNoHide&&this.showLabel()},_addLabelRevealHandlers:function(){this.on("mouseover",this.showLabel,this).on("mouseout",this.hideLabel,this),t.Browser.touch&&this.on("click",this.showLabel,this)},_removeLabelRevealHandlers:function(){this.off("mouseover",this.showLabel,this).off("mouseout",this.hideLabel,this),t.Browser.touch&&this.off("click",this.showLabel,this)},_moveLabel:function(t){this.label.setLatLng(t.latlng)}},t.Icon.Default.mergeOptions({labelAnchor:new t.Point(9,-20)}),t.Marker.mergeOptions({icon:new t.Icon.Default}),t.Marker.include(t.BaseMarkerMethods),t.Marker.include({_originalUpdateZIndex:t.Marker.prototype._updateZIndex,_updateZIndex:function(t){var e=this._zIndex+t;this._originalUpdateZIndex(t),this.label&&this.label.updateZIndex(e)},_originalSetOpacity:t.Marker.prototype.setOpacity,setOpacity:function(t,e){this.options.labelHasSemiTransparency=e,this._originalSetOpacity(t)},_originalUpdateOpacity:t.Marker.prototype._updateOpacity,_updateOpacity:function(){var t=0===this.options.opacity?0:1;this._originalUpdateOpacity(),this.label&&this.label.setOpacity(this.options.labelHasSemiTransparency?this.options.opacity:t)},_originalSetLatLng:t.Marker.prototype.setLatLng,setLatLng:function(t){return this.label&&!this._labelNoHide&&this.hideLabel(),this._originalSetLatLng(t)}}),t.CircleMarker.mergeOptions({labelAnchor:new t.Point(0,0)}),t.CircleMarker.include(t.BaseMarkerMethods),t.Path.include({bindLabel:function(i,n){return this.label&&this.label.options===n||(this.label=new e(n,this)),this.label.setContent(i),this._showLabelAdded||(this.on("mouseover",this._showLabel,this).on("mousemove",this._moveLabel,this).on("mouseout remove",this._hideLabel,this),t.Browser.touch&&this.on("click",this._showLabel,this),this._showLabelAdded=!0),this},unbindLabel:function(){return this.label&&(this._hideLabel(),this.label=null,this._showLabelAdded=!1,this.off("mouseover",this._showLabel,this).off("mousemove",this._moveLabel,this).off("mouseout remove",this._hideLabel,this)),this},updateLabelContent:function(t){this.label&&this.label.setContent(t)},_showLabel:function(t){this.label.setLatLng(t.latlng),this._map.showLabel(this.label)},_moveLabel:function(t){this.label.setLatLng(t.latlng)},_hideLabel:function(){this.label.close()}}),t.Map.include({showLabel:function(t){return this.addLayer(t)}}),t.FeatureGroup.include({clearLayers:function(){return this.unbindLabel(),this.eachLayer(this.removeLayer,this),this},bindLabel:function(t,e){return this.invoke("bindLabel",t,e)},unbindLabel:function(){return this.invoke("unbindLabel")},updateLabelContent:function(t){this.invoke("updateLabelContent",t)}}),e},window);
</script>
<script>
var itm = [{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":43,"Points":0.0,"Polyline":"qobxHcdujCADC???ICKK??COEMGI??EEGAE?","CalculatedAvgSpeed":21.6},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":35,"Points":0.0,"Polyline":"sqbxH}eujCG???GDGFEJ??CJAJ?J#J","CalculatedAvgSpeed":21.6},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":257,"Points":0.0,"Polyline":"urbxHscujC#LDHDH??#L?^??A`#GlBKdCKzCIvAInAI|#","CalculatedAvgSpeed":31.68},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":50.0,"DistanceInMeters":300,"Points":0.0,"Polyline":"etbxHkltjCGt#Kx#Ix#O~#Kp#Kr#Qv#]hBaAfF??M\\??G#GBGDEH","CalculatedAvgSpeed":65.73333},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":42,"Points":0.0,"Polyline":"i{bxH}ssjCCHCHAJ???NBN??BL??Cj#","CalculatedAvgSpeed":29.4},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":105,"Points":0.0,"Polyline":"o{bxHcpsjCqApG","CalculatedAvgSpeed":43.2},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":50.0,"DistanceInMeters":656,"Points":0.0,"Polyline":"a~bxHqgsjCUpA??Ot#Sv#Uz#Wv#??KZ??IV??i#bBW~#Ol#Mp#??G\\Gr#Ej#Cv#?r#??GdCCp#El#Gh#Eh#??Kl#Id#Kf#??Kb#Mb#K^MZO^Q^Wd#??S\\UXWXUT]\\","CalculatedAvgSpeed":68.21053},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":70.0,"DistanceInMeters":716,"Points":0.0,"Polyline":"_ocxHusqjCi#b#cG|EsHbGs#l#a#`#YZSXU\\U^Sb#Sd#Q`#M`#Md#Oh#Kf#??ET??Od#Ox#QdAGl#C\\AZ","CalculatedAvgSpeed":79.8},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":70.0,"DistanceInMeters":21,"Points":0.0,"Polyline":"imdxHalpjCAT?h#","CalculatedAvgSpeed":72.0},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":62,"AvgAllowedSpeed":92.16,"DistanceInMeters":2465,"Points":0.0,"Polyline":"kmdxHajpjC?`A??#nAHrCTpH??HtG??f#db#^rZ??FbGNvL#x#Dx#Br#Dn#??Dn#JbAJfATjBrBnQ??`Flc#??bBxN??RfB??`BjN","CalculatedAvgSpeed":93.24},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":72.76,"DistanceInMeters":2533,"Points":0.0,"Polyline":"iucxHqpijC#F??vCbWfBbORdBZ`C??xAlK\\rCVzBn#jG~ArO??h#fF??h#dFfAjJ??tApL??`Ex]??h#vE??jBjP??D^??|#rH??vB`R","CalculatedAvgSpeed":100.28},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":90.0,"DistanceInMeters":1133,"Points":0.0,"Polyline":"qjbxH{vbjC\\xC??RfB??p#|F??fAnJ??X|B??b#vD??l#dF??f#lE??pArKVxB??H|#Jv#Bd#B^Bb#FdBDtA??FbCBr#???Z?\\A`#Af#Er#K|A??UrC","CalculatedAvgSpeed":98.42553},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":93.94,"DistanceInMeters":1036,"Points":0.0,"Polyline":"w|axHus_jCSdC??_AxJ??YvC??YnC??cAfKCV??qAxM??QdB??ShB??a#dE??WbC??EV??U|B??YjC??C`#??K~#??MdA??c#fE","CalculatedAvgSpeed":84.43636},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":90.0,"DistanceInMeters":2011,"Points":0.0,"Polyline":"qlbxHgy|iC[zC??Gl#??c#hE??[xC??Gj#??AL??MpA??Gj#??Iv#??CR??OrA??CZ??O|A??e#hE??W`C??CV??OvAC\\E`#AT??A\\C^Ad#UjJ??UzI??Cl#??_#bOAd#Cp#Cp#C\\C`#Cb#CTEZ??CR??[pB_#bC??w#|E??aAjG??g#vC??e#lC??a#|B??Kj#??EX??i#zC??GZ??a#`C??_AhF??[bB??SfA??u#hE??s#dE","CalculatedAvgSpeed":80.48},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":82,"AvgAllowedSpeed":57.02,"DistanceInMeters":245,"Points":0.0,"Polyline":"glcxHyjwiCG\\Mr#Gf#??Gv#Cf#Af#Ab##f#?b##f#Bb#??Dj#??D`#D\\F`#Jd#Jd#Ld#","CalculatedAvgSpeed":56.475},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":86,"AvgAllowedSpeed":52.73,"DistanceInMeters":1282,"Points":0.0,"Polyline":"mkcxH{tviCNf#N^NZLV??LR??JR??bA`B^r#??|#zA??f#`A??LR??HP??f#~#??P`#Tf#??NXN\\??Vn#??DL??Xr#Rb#??t#pB??Rf#??r#fB??Rh#??Pb#??LX??p#dB??HR??#D??JV??HP??`#fA??LX??j#zA??LX??n#bB??`AdC??Pd#??N^??FN??Vn#??FP??`#`A??|#|B??~#`C??Xt#??^bA??Zt#??h#vA??^~#??Nb#??h#rA??~#bC","CalculatedAvgSpeed":53.16},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":41,"AvgAllowedSpeed":83.09,"DistanceInMeters":1446,"Points":0.0,"Polyline":"q|axHqzsiCTh#??Rh#??JZ??`#bA??FN??Tj#??t#jB??j#vA??rHfRPb#L^L`#J\\J^Pr#b#fB??z#dD??r#rC??nB`I??lA~E??fCbK??XjA??p#jCXdAz#xC??p#xB??fAnD??\\hA??Rr#PE","CalculatedAvgSpeed":83.82857}];
var polylines = [], points = [], behavePolylines = [];
$(function(){
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
}
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
function getColor(calculated, allowed){
var diff = calculated - allowed;
if(diff <=0){
return "#0ea00f";
} else if(diff >0 && diff <= 15){
return "#ff6a00"
} else if(diff > 15){
return "#ff0000"
} else return "#000"
}
function renderTrip (trip) {
//if (!data.success) return;
// var trip = JSON.parse(data.trip);
$.each(polylines, function (e, val) {
map.removeLayer(val);
});
var tripPolyPoints = L.PolylineUtil.decode(data.POLY);
var tripPoly = L.polyline(tripPolyPoints,
{
color: "#000000",
opacity: 0.6,
weight: 4
});
tripPoly.addTo(map);
map.fitBounds(tripPoly.getBounds());
polylines.push(tripPoly);
for (var i = 0; i < trip.length; i++) {
var calculated = (trip[i].CalculatedAvgSpeed).toFixed(1);
var allowed = (trip[i].AvgAllowedSpeed).toFixed(1);
var distance = (trip[i].DistanceInMeters / 1000.0).toFixed(2);
var polylinePoints = L.PolylineUtil.decode(trip[i].Polyline);
var polyline = L.polyline(polylinePoints, {
color: getColor(calculated, allowed),
opacity: 1,
weight: 8
}).bindLabel('Średnia prędkość: ' + calculated + ' KM/H<br>Średnia dopuszczalna prędkość: '
+ allowed + ' KM/H<br>Długość odcinka: ' + distance + ' KM');
polyline.addTo(map);
polylines.push(polyline);
}
var origPolyPoints = L.PolylineUtil.decode(data.bfPoly);
var origPoly = L.polyline(origPolyPoints,
{
color: "#0000ff",
opacity: 0.5,
weight: 5
});
origPoly.addTo(map);
polylines.push(origPoly);
}
renderTrip(itm);
});
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_KAY&callback=initMap"
async defer></script>
</body>
</html>
Error Message :
Uncaught (in promise) yd {message: "initMap is not a function", name:
"InvalidValueError", stack: "Error↵ at new yd message: "initMap is
not a function" name: "InvalidValueError"
Your initMap function needs to be placed in global scope so that the Map API's callback can find and call this function.
<script>
var itm = [];
var polylines = [],
points = [],
behavePolylines = [];
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8
});
}
$(function() {
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
...
});
</script>
Please check out related thread Google Maps Javascript API not loading reliably
Hope this helps!

angular-google-maps: how to get current model in ui-gmap-markers

I'm trying to load icon for each mark. each mark's icon is different.
I have a function "getIcon", it will needs the uid from each binding model(item.Uid).
If I pass "this" to getIcon, it is undefined.
It seems like there is no way to find the current model.
I will have to use "ui-gmap-markers" here not "ui-gmap-marker"
This options works really weird.
<ui-gmap-markers models="items" idkey="'Uid'"
options="{icon: getIcon(this, map.zoom)}"
coords="'self'" icon="'icon'">
</ui-gmap-markers>
In this example this refers to ui-gmap-markers directive isolated scope and the model property is not accessible since it belongs to child scope.
You could consider the following approach to bind icon marker based on map zoom.
First, let's introduce an array of icons per every zoom level:
$scope.zoomIcons = {};
var althabet = "abcdefghijklmnopqrstuvwxyz".toUpperCase().split("");
var l = 0;
althabet.forEach(function(ch){
$scope.zoomIcons[l] = 'http://www.google.com/mapfiles/marker' + ch + '.png';
l++;
});
Then let's specify marker icon using icon directive attribute:
<ui-gmap-markers models="items" idkey="'Uid'" coords="'self'" icon="'icon'">
</ui-gmap-markers>
where icon property along with another properties will be initialized per every marker(see below example for a more details)
And the last step would be to update marker icon once the map zoom is changed as shown below:
$scope.$watch(function () { return $scope.map.zoom; }, function (newZoom, oldZoom) {
if(newZoom != oldZoom){
console.log('Zoom:' + newZoom + ':' + oldZoom);
$scope.items.forEach(function(item){
item.icon = $scope.getIcon(newZoom);
});
}
}, true);
Working example
var appMaps = angular.module('appMaps', ['uiGmapgoogle-maps']);
appMaps.controller('mainCtrl', function($scope) {
$scope.map = {
center: { latitude: 40.1451, longitude: -99.6680 },
zoom: 4,
options: { scrollwheel: false }
};
$scope.zoomIcons = {};
var althabet = "abcdefghijklmnopqrstuvwxyz".toUpperCase().split("");
var l = 0;
althabet.forEach(function(ch){
$scope.zoomIcons[l] = 'http://www.google.com/mapfiles/marker' + ch + '.png';
l++;
});
var getRandomLat = function() {
return Math.random() * (180.0) - 90.0;
};
var getRandomLng = function () {
return Math.random() * (360.0) - 180.0;
};
var createRandomMarker = function(i) {
var item = {
latitude: getRandomLat(),
longitude: getRandomLng(),
title: '#' + i,
show: true,
Uid: i,
icon: $scope.getIcon($scope.map.zoom)
};
return item;
};
$scope.getIcon = function(zoom) {
return { url: $scope.zoomIcons[zoom] };
};
$scope.items = [];
for (var i = 0; i < 160; i++) {
$scope.items.push(createRandomMarker(i));
}
$scope.$watch(function () { return $scope.map.zoom; }, function (newZoom, oldZoom) {
if(newZoom != oldZoom){
console.log('Zoom:' + newZoom + ':' + oldZoom);
$scope.items.forEach(function(item){
item.icon = $scope.getIcon(newZoom);
});
}
}, true);
});
html, body, #map_canvas {
height: 100%;
width: 100%;
margin: 0px;
}
#map_canvas {
position: relative;
}
.angular-google-map-container {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
<script src="https://code.angularjs.org/1.3.14/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src="http://rawgit.com/angular-ui/angular-google-maps/2.0.X/dist/angular-google-maps.js"></script>
<div id="map_canvas" ng-app="appMaps" ng-controller="mainCtrl">
<ui-gmap-google-map center="map.center" zoom="map.zoom" options="map.options" events="map.events">
<ui-gmap-markers models="items" idkey="'Uid'"
coords="'self'" icon="'icon'" >
</ui-gmap-markers>
</ui-gmap-google-map>
</div>

Add to Angular Model from Outside of Controller

I want to call the addRectangleMethod method from the javascript in my code so that I can get server side information into the Angular datamodel. I keep getting the error that the method I am trying to call is undefined. The angular is in typescript.
Html
<!DOCTYPE html>
<html >
<head>
<style>
#map-canvas {
width: 800px;
height: 600px;
text-align: center;
}
</style>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/PosCtrl.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaL- xHTY5NYNS6StKvA0TGsZYx3D44"></script>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script>
//angular.element($('#Test')).scope().PositionCtrl.addRectangle();
console.log($('#Test'));
var appElement = document.querySelector('[ng-app=myApp]');
var $scope = angular.element(appElement).scope();
$scope.$apply(function () {
$scope.addRectangleMethod(2,2,2,2,"Hello");
});
</script>
</head>
<body id="Test" ng-app="myApp" ng-controller="PositionCtrl as Pos" style="display: inline-block; margin: 0px 0px 0px 550px; text-align: center;">
<div style="height: 100%; width: 100%;">
<div id="map-canvas"></div>
</div>
<div>
<form>
<ul>
<li ng-repeat="x in Pos.rectangles"><input ng-model="x.Name" ng- change="x.tangleChange()" /> <b>South West Corner</b> {{x.Shape.getBounds().O.O}} , {{x.Shape.getBounds().j.j}} <b>North East Corner</b>{{x.Shape.getBounds().O.j}} , {{x.Shape.getBounds().j.O}}<button ng-click="Pos.deleteRec(x)">Delete</button> </li>
</ul>
<button ng-click="Pos.save()">Save Settings</button>
<button ng-click="Pos.addRectangle()">Add Area</button>
</form>
</div>
</body>
#Scripts.Render("~/bundles/bootstrap")
</html>
Angular
/// <reference path="../../OciCP2.0/Scripts/typings/googlemaps/google.maps.d.ts" />
/// <reference path="../../OcCP2.0/Scripts/typings/angularjs/angular.d.ts" />
class Rectangle {
//Rectangle class properties
Shape: google.maps.Rectangle;
InfoWindow: google.maps.InfoWindow;
Name: string;
constructor(map: google.maps.Map, pt1: google.maps.LatLng, pt2: google.maps.LatLng, info: string, $scope: ng.IScope) {
//Set rectangle Options
var options: google.maps.RectangleOptions = {
editable: true,
draggable: true
}
//Create Rectangle
this.Shape = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
bounds: new google.maps.LatLngBounds(pt1, pt2),
});
//Attach Options to rectangle
this.Shape.setOptions(options);
this.Name = info;
//Create info window
this.InfoWindow = new google.maps.InfoWindow({
content: info,
position: pt1
});
this.InfoWindow.setPosition(this.Shape.getBounds().getNorthEast());
this.InfoWindow.open(map);
google.maps.event.addListener(this.Shape, 'bounds_changed',() => {
this.InfoWindow.setPosition(this.Shape.getBounds().getNorthEast());
$scope.$apply();
this.InfoWindow.open(map)
});
}
tangleChange() {
//Keep info content up to date
this.InfoWindow.setContent(this.Name);
}
}
class PositionCtrl {
//Proporties of the controller
MyMap: google.maps.Map;
marker: google.maps.Marker;
event: google.maps.event;
rectangles: Rectangle[];
lat: number; long: number; rad: number;
//Save the changes
save() {
alert("Settings Saved");
}
constructor(private $scope: ng.IScope) {
this.lat = 20;
this.long = 20;
this.rad = 10000;
this.rectangles = new Array<Rectangle>();
//Create map and bind to element
var mapCanvas = document.getElementById('map-canvas');
var mapOptions = {
center: new google.maps.LatLng(Number(this.lat), Number(this.long)),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDoubleClickZoom: true
}
this.MyMap = new google.maps.Map(mapCanvas, mapOptions)
}
//Add rectangle to page
addRectangle() {
//Add rectangle to array
this.rectangles.push(
new Rectangle(this.MyMap,
new google.maps.LatLng(this.MyMap.getCenter().lat() - .5, this.MyMap.getCenter().lng() - .5),
new google.maps.LatLng(this.MyMap.getCenter().lat() + .5, this.MyMap.getCenter().lng() + .5), "Enter Name", this.$scope)
);
console.log(this.rectangles);
}
addRectangleMethod(top, bottom, left, right, name) {
console.log("Sucess");
this.rectangles.push(
new Rectangle(this.MyMap,
new google.maps.LatLng(left, bottom),
new google.maps.LatLng(right, top), name, this.$scope)
);
}
//Remove Rectangle from map
deleteRec(x: Rectangle) {
for (var i = 0; i < Rectangle.length; i++) {
if (this.rectangles[i].InfoWindow.getContent() == x.InfoWindow.getContent()) {
x.Shape.setMap(null);
x.InfoWindow.close();
this.rectangles.splice(i, 1);
}
}
this.$scope.$apply();
}
}
var myApp = angular.module('myApp', []);
myApp.controller("PositionCtrl", ["$scope", PositionCtrl]);
Bind the addRectangleMethod from your class to your $scope
constructor(private $scope: ng.IScope) {
this.$scope.addRectangleMethod = () => this.addRectangleMethod();

Knockout JS calling wrong object from array

I'm making a system that allows reorder of products. Each display area in a shop is a unit, which has several groups which (in turn) house several products. I am currently using knockout to load a unit via a select element, then cycling through the groups providing quantity fields for products.
This all works, but I need a select all button which sets all products in a group to have a quantity of 1. I have given the group object a function (allForOne()) which should cycle through each product in the group's observable array and set this to one, however, no matter how I bind this to the #allInOne button, it always applies this to the last group in the unit's observable group array.
For example, when the code first loads, I want to select all in the first group and make their quantity one, but it only changes the quantity in the last group.
I use the same selector in the same binding to "alert" the correct unit name (based on the unit's groupCounter property) before I call the function, but it returns two different values.
Why is it not affecting the current group? I can't work this out for the life of me and Google hasn't been much help.
Here is a JSFiddle, or you can see the code below:
Here is the view:
<div class="select-container">
<label for="unit" class="label">Unit</select>
<select name="unit" class="select-unit drop-shadow" data-bind='options: units, optionsText: "skuName", optionsCaption: "Select...", value: unit'></select>
<div>
</div>
<div class="unit-image" data-bind="with: unit">
<img data-bind="attr{ src: $parent.unit().image, alt: $parent.unit().name }">
</div>
<div data-bind="with: unit" class="clearfix products-container">
<div class="clearfix" data-bind="with: $parent.groups()[$parent.groupCounter()]">
<!--<div data-bind="style: { width: (((parseInt(limit) / parseInt($root.totalLimit)) * 100) - 1)+'%', marginRight: '0.5%', marginLeft: '0.5%'}" style="display: block; position: relative; float: left;">-->
<h2 data-bind="text: name" style="margin-bottom: 12px;"></h2>
<div data-bind="foreach: {data: products/*, beforeRemove: hideProduct, afterRender: showProduct*/}">
<div class="prod-page-product drop-shadow" data-bind="style: { width: ((100 / $parent.limit) - 1)+'%', marginRight: '0.5%', marginLeft: '0.5%'}">
<p><span data-bind='text: sku'></span></p>
<div>
<div class="add-container">+</div>
<div><input type="number" class="is-numeric" min="0" data-bind='value: quantity, valueUpdate: "afterkeydown"' /></div>
<div class="remove-container">-</div>
</div>
</div>
</div>
<!--</div>-->
<div class="clearfix">
<button id="nextProdGroup" class="products-button float-left" data-bind="enable:$root.firstGroupBool, click: $root.prevGroup, style: { width: productWidth, maxWidth: ((100/4) - 1)+'%', marginRight: '0.5%', marginLeft: '0.5%'}">Prev Group</button>
<button id="prevProdGroup" class="products-button float-left" data-bind="enable:$root.nextGroupBool, click: $root.nextGroup, style: { width: productWidth, maxWidth :((100/4) - 1)+'%', marginRight: '0.5%', marginLeft: '0.5%'}">Next Group</button>
<!--This is the offending button binding-->
<button id="allForOne" class="products-button float-left" data-bind="click: function() { alert('Expected Group: '+$root.groups()[$root.groupCounter()].name()); $root.groups()[$root.groupCounter()].allForOne()}, style: { width: productWidth, maxWidth :((100/4) - 1)+'%', marginRight: '0.5%', marginLeft: '0.5%'}">This is what messes up</button>
</div>
</div>
</div>
<div id="shadow-overlay" class="ui-overlay" data-bind="visible: loaderBool">
<div class="ui-widget-overlay"></div>
<div id="top-overlay" class="ui-overlay" style="width: 50%; height: 80%; position: absolute; left: 25%; top: 10%;"></div>
<div id="ajax-loading-container">
<p class="ajax-loader-text">Loading...</p>
</div>
Here is the viewModel:
var Product = function(id, sku) {
var self = this;
//Properties
self.id = ko.observable(id);
self.sku = ko.observable(sku);
self.quantity = ko.observable(0);
//Methods
self.incrementQuantity = function(product) {
var previousQuantity = parseInt(self.quantity());
self.quantity(previousQuantity+1);
};
self.decrementQuantity = function(product) {
var previousQuantity = parseInt(self.quantity());
if(self.quantity() > 0)
{
self.quantity(previousQuantity-1);
}
};
};
//The object with the called function
var Group = function(name, limit, productList)
{
self = this;
//Properties
self.name = ko.observable(name);
self.nametwo = name;
self.limit = limit;
self.products = ko.observableArray();
self.productWidth = ko.pureComputed(function(a, b)
{
return ((100 / limit) - 1)+'%';
});
//Methods
//---------The offending function
self.allForOne = function() {
alert("Returned Group: "+self.name());
ko.utils.arrayForEach(self.products(), function(product) {
product.quantity(1);
});
};
//Initial population
$.each(productList, function(key, product) {
self.products.push(new Product(product.id, product.sku));
});
}
var Unit = function() {
var self = this;
//Properties
self.unit = ko.observable();
self.groups = ko.observableArray();
self.groupCounter = ko.observable(0);
self.lastGroup = ko.observable(true);
self.totalLimit = 0;
self.saved = true;
self.loaderBool = ko.observable(false);
self.firstGroupBool = ko.pureComputed(function()
{
return (self.groupCounter() < 1 ? false : true);
});
self.nextGroupBool = ko.pureComputed(function()
{
return (self.lastGroup() == true ? false : true);
});
self.unit.subscribe(function() {
self.populateGroup();
});
//Methods
self.onLoadCheck = (function() {
if(units.length == 1)
{
self.unit(units[0]);
}
});
self.populateGroup = function() {
self.loaderBool(true);
self.groups([]);
//setTimeout(function() {
self.TotalLimit = 0;
$.each(self.unit().group, function(groupKey, groupVal) {
//setTimeout(function() {
self.groups.push(new Group(groupVal.name, groupVal.limit, groupVal.product));
//}, 0);
self.totalLimit += parseInt(groupVal.limit);
});
self.groupCounter(0);
self.lastGroup(false);
self.loaderBool(false);
//}, 0);
console.log(self.groups());
console.log(self.groups()[self.groupCounter()]);
};
self.prevGroup = function(a, b) {
self.save(a, b);
var groupCounter = parseInt(self.groupCounter());
self.groupCounter(groupCounter-1);
if(self.groupCounter() != self.groups().length-1)
{
self.lastGroup(false);
}
};
self.nextGroup = function(a, b) {
self.save(a, b);
var groupCounter = parseInt(self.groupCounter());
self.groupCounter(groupCounter+1);
if(self.groupCounter() == self.groups().length-1)
{
self.lastGroup(true);
}
};
self.save = function(a, b) {
var productsToSave = self.groups()[self.groupCounter()].products();
var dataToSave = $.map(productsToSave, function(line) {
return {
id: line.id(),
quantity: line.quantity()
}
});
if(productsToSave.length == 0)
{
dialog("Error", "You cannot submit before you add products.");
return false;
}
else
{
var caller = $(b.toElement);
//sendOrder("baskets/update", {products: dataToSave}, caller);
if(caller.attr("id") == "submitProdGroup")
{
window.location = baseUrl+"basket";
}
}
};
};
Take a look at this: http://jsfiddle.net/rks5te7v/5/ I rewrote your code using a viewmodel like this (look at the url above):
function ViewModel() {
var self = this;
self.units = ko.observableArray();
self.chosenUnit = ko.observable();
self.chosenGroup = ko.observable(0);
self.goToNextGroup = function () {
self.chosenGroup(parseInt(self.chosenGroup()) + 1);
};
self.goToPrevGroup = function () {
self.chosenGroup(parseInt(self.chosenGroup()) - 1);
};
self.setGroupAs1 = function () {
var products = self.chosenUnit().groups()[self.chosenGroup()].products();
ko.utils.arrayForEach(products, function (product) {
product.quantity(1);
});
};
//loading data
var product1 = new Product('1', 'P1');
var product2 = new Product('2', 'P2');
var product3 = new Product('3', 'P3');
var product4 = new Product('4', 'P4');
var group1 = new Group('G1', [product1, product2]);
var group2 = new Group('G2', [product3, product4]);
self.units.push(new Unit('Unit 1', [group1, group2]));
};
Does it solve your problem? :)

Google maps listener event acts like a click even though it is a mouseover

I am adding these two google.maps.event.addListener events
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
markerIconAcademicCenter.url = 'MapIcons/Circle32.png'
});
google.maps.event.addListener(markerAcademicCenter, "mouseout", function (e) {
markerIconAcademicCenter.url = 'MapIcons/Circle64.png'
});
below this marker that already has a click event.
google.maps.event.addListener(markerAcademicCenter, "click", function (e) {
$(".campusMapInfoPanel > div").appendTo($(".InfoStorageDiv"));
$(".InfoPanelAcademicCenter").appendTo($(".campusMapInfoPanel"));
this.setZIndex(google.maps.Marker.MAX_ZINDEX + 1);
setZoomWhenMarkerClicked();
CampusMap.setCenter(markerAcademicCenter.getPosition());
});
The markerIconAcademicCenter.url is already set to Circle64 above these events. I expect the page to load with the larger circle — 64x64 — the switch back and forth as I hover and leave the marker area.
I'm having two problems with this
Nothing happens when I mouseover the marker, but it does happen when I click. On the initial click after the page loads, the map zooms and centers on the building and the marker image resizes. If I click on the building again, nothing else happens, but:
if I click on a menu link that triggers the click event, function buildingFocus(markerName) {google.maps.event.trigger(markerName, "click");} that function resets the icon as if it were the mouseout event.
To test this unexpected behavior further, I commented out each event one at a time. To clarify that something was actually happening, I first changed the initial image to clear.png.
When I took out the mouseover event, the image did not change when I clicked either the building event or the menu link as my first click after the page loaded. Before I removed the mouseover event, clicking on the menu as my second click after page load changed the icon to the mouseout image, but now clicking on the building causes this.
When I took out the mouseout event, clicking on the building as the first click made the icon change to the mouseover image, and clicking again on either area did nothing further. If I clicked on the menu link as the first or future clicks the image didn't change, but it did as soon as I clicked on the building.
When I took the click event out, the image never changed. By itself, the click event works as expected with both locations.
The icon of a marker is not an MVCObject, the API will not observe changes of the icon-properties.
You must modify the url of the icon and then call setIcon to apply the changes:
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
var icon = this.getIcon();
icon.url = 'url/to/icon';
this.setIcon(icon);
});
But I wouldn't suggest it, when you use the icon for multiple markers changing the url(or other properties) will affect the original icon markerIconAcademicCenter (markers use a reference to the original object). You better create a copy with a modified url:
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
var icon = this.getIcon(),copy={};
for(var k in icon){
copy[k]=icon[k];
}
copy.url= 'url/to/icon';
this.setIcon(copy);
});
Try using this :
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
markerIconAcademicCenter.setIcon('url to icon');
});
instead of code below :
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
markerIconAcademicCenter.url = 'MapIcons/Circle32.png'
});
This will sort out your problem of icon size change on mouseover and mouseout problem.
You can check the code below, so that you will be clear what I mean to say :
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Map Simple</title>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=places"></script>
<script type="text/javascript">
var map, places, iw;
var markers = [];
var autocomplete;
var options = {
//types: ['(cities)'],
//componentRestrictions: {country: 'us'}
};
var geocoder = new google.maps.Geocoder();
function initialize() {
var myLatlng = new google.maps.LatLng(37.783259, -122.402708);
var myOptions = {
zoom: 12,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
places = new google.maps.places.PlacesService(map);
google.maps.event.addListener(map, 'tilesloaded', tilesLoaded);
autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'), options);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
showSelectedPlace();
});
}
function tilesLoaded() {
google.maps.event.clearListeners(map, 'tilesloaded');
google.maps.event.addListener(map, 'zoom_changed', search);
google.maps.event.addListener(map, 'dragend', search);
search();
}
function showSelectedPlace() {
clearResults();
clearMarkers();
var place = autocomplete.getPlace();
map.panTo(place.geometry.location);
markers[0] = new google.maps.Marker({
position: place.geometry.location,
map: map
});
iw = new google.maps.InfoWindow({
content: getIWContent(place)
});
iw.open(map, markers[0]);
search();
}
function search() {
var type;
for (var i = 0; i < document.controls.type.length; i++) {
if (document.controls.type[i].checked) {
type = document.controls.type[i].value;
}
}
autocomplete.setBounds(map.getBounds());
var search = {
bounds: map.getBounds()
};
if (type != 'establishment') {
search.types = [ type ];
}
places.search(search, function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
clearResults();
clearMarkers();
for (var i = 0; i < 9; i++) {
markers[i] = new google.maps.Marker({
position: results[i].geometry.location,
animation: google.maps.Animation.DROP
});
google.maps.event.addListener(markers[i], 'mouseover', animate(i));
google.maps.event.addListener(markers[i], 'mouseout', reanimate(i));
google.maps.event.addListener(markers[i], 'click', getDetails(results[i], i));
setTimeout(dropMarker(i), i * 100);
//addResult(results[i], i);
mygetDetails(results[i], i);
}
}
})
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
if (markers[i]) {
markers[i].setMap(null);
markers[i] == null;
}
}
}
function dropMarker(i) {
return function() {
markers[i].setMap(map);
}
}
//Function to animate markers on there hover
function animate(locationCount){
return function(){
markers[locationCount].setIcon('https://mts.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=2');
$("#addressSpan"+locationCount).css('font-weight', '700');
$("#addressSpan"+locationCount).css('color', '#ff0000');
}
}
//Function to remove animation of markers on there hover
function reanimate(locationCount){
return function(){
markers[locationCount].setIcon('https://mts.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=1');
$("#addressSpan"+locationCount).css('font-weight', '');
$("#addressSpan"+locationCount).css('color', '');
}
}
function addResult(result, i) {
if(i<=9){
var results = document.getElementById("results");
var tr = document.createElement('tr');
tr.style.backgroundColor = (i% 2 == 0 ? '#F0F0F0' : '#FFFFFF');
tr.click = function() {
google.maps.event.trigger(markers[i], 'click');
};
var iconTd = document.createElement('td');
var nameTd = document.createElement('td');
var addressTd = document.createElement('td');
var icon = document.createElement('img');
icon.src = result.icon;
icon.setAttribute("class", "placeIcon");
icon.setAttribute("className", "placeIcon");
var name = document.createTextNode(result.name);
var address = document.createTextNode(result.formatted_address);
iconTd.appendChild(icon);
nameTd.appendChild(name);
addressTd.appendChild(address);
tr.appendChild(iconTd);
tr.appendChild(nameTd);
tr.appendChild(addressTd);
results.appendChild(tr);
}
}
function clearResults() {
var results = document.getElementById("results");
while (results.childNodes[0]) {
results.removeChild(results.childNodes[0]);
}
}
function clearResults1() {
var results = document.getElementById("results1");
while (results.childNodes[0]) {
results.removeChild(results.childNodes[0]);
}
}
function getDetails(result, i) {
return function() {
places.getDetails({
reference: result.reference
}, showInfoWindow(i));
}
}
function mygetDetails(result, i) {
return places.getDetails({
reference: result.reference
}, function(place, status){
if (status == google.maps.places.PlacesServiceStatus.OK) {
addResult(place, i);
}
});
}
function showInfoWindow(i) {
return function(place, status) {
if (iw) {
iw.close();
iw = null;
}
if (status == google.maps.places.PlacesServiceStatus.OK) {
iw = new google.maps.InfoWindow({
content: getIWContent(place)
});
iw.open(map, markers[i]);
}
}
}
function getIWContent(place) {
var content = "";
content += '<table><tr><td>';
content += '<img class="placeIcon" src="' + place.icon + '"/></td>';
content += '<td><b>' + place.name + '</b>';
content += '</td></tr></table>';
return content;
}
$(function(){
$("#autocomplete").keyup(function(){
clearResults1();
geocoder.geocode({"address": $(this).val()}, function(data, status) {
if (status == google.maps.GeocoderStatus.OK) {
$.each(data, function(int_index,value) {
var results = document.getElementById("results1");
var tr = document.createElement('tr');
tr.style.backgroundColor = (int_index% 2 == 0 ? '#F0F0F0' : '#FFFFFF');
var nameTd = document.createElement('td');
var name = document.createTextNode(value.formatted_address);
nameTd.appendChild(name);
tr.appendChild(nameTd);
results.appendChild(tr);
});
}
});
});
});
</script>
<style>
body {
font-family: sans-serif;
}
#map_canvas {
position: absolute;
width: 399px;
height: 399px;
top: 25px;
left: 0px;
border: 1px solid grey;
}
#listing {
position: absolute;
width: 200px;
height: 360px;
overflow: auto;
left: 401px;
top: 65px;
cursor: pointer;
}
#listing1 {
position: absolute;
width: 200px;
height: 360px;
overflow: auto;
left: 601px;
top: 65px;
cursor: pointer;
}
#controls {
width: 200px;
position: absolute;
top: 0px;
left: 400px;
height: 60px;
padding: 5px;
font-size: 12px;
}
.placeIcon {
width: 16px;
height: 16px;
margin: 2px;
}
#resultsTable, #resultsTable1{
font-size: 10px;
border-collapse: collapse;
}
#locationField {
width: 400px;
height: 25px;
top: 0px;
left: 0px;
position: absolute;
}
#autocomplete {
width: 400px;
}
</style>
</head>
<body style="margin:0px; padding:0px;" onLoad="initialize()">
<div id="locationField">
<input id="autocomplete" type="text" />
</div>
<div id="controls">
<form name="controls">
<input type="radio" name="type" value="establishment" onClick="search()" checked="checked"/>All<br/>
<input type="radio" name="type" value="restaurant" onClick="search()" />Restaurants<br/>
<input type="radio" name="type" value="lodging" onClick="search()" />Lodging
</form>
</div>
<div id="map_canvas"></div>
<div id="listing"><table id="resultsTable"><tr><td><h3>Suggested<br>Locations</h3></td></tr><tbody id="results"></tbody></table></div>
<div id="listing1"><table id="resultsTable1"><tr><td><h3>Suggested<br>Address</h3></td></tr><tbody id="results1"></tbody></table></div>
</body>
</html>
This is a working example.

Categories

Resources