I am integrating local storage into the map functionality for GeoDirectory for WordPress. The functionality stores the map marker and WordPress post data in storage, then loads it in when a user revisits the map page after viewing a listing. A live example can be viewed here.
I have successfully stored the map marker's and WordPress data in storage using the storeUserMarker
function and can retrieve it when page the page loads using loadUserMarker
. I have included both functions below.
function storeUserMarker(item, map_canvas) {
let markerId, markerTitle, markerContent, markerIcon, markerAnchor, markerPosition;
markerId = item.id;
markerTitle = item.title;
markerContent = html;
markerIcon = item.icon = {
url: item.icon,
origin: new google.maps.Point(0, 0),
anchor: item.anchorPoint
};
markerAnchor = item.anchorPoint;
markerPosition = item.position;
localStorage.setItem( 'id', markerId );
localStorage.setItem( 'title', markerTitle );
localStorage.setItem( 'content', markerContent );
localStorage.setItem( 'icon', JSON.stringify(markerIcon) );
localStorage.setItem( 'anchor', JSON.stringify(markerAnchor) );
localStorage.setItem( 'position', JSON.stringify(markerPosition) );
}
function loadUserMarker(item, map_canvas) {
let markerId = localStorage.getItem( 'id' );
let markerTitle = localStorage.getItem( 'title' );
let markerContent = localStorage.getItem( 'content' );
let markerIcon = JSON.parse(localStorage.getItem( 'icon' ));
let markerAnchor = JSON.parse(localStorage.getItem( 'anchor' ));
let markerPosition = JSON.parse(localStorage.getItem( 'position' ));
let marker = {
id: markerId,
title: markerTitle,
icon: markerIcon,
anchorPoint: markerAnchor,
position: markerPosition,
visible: true,
clickable: true
};
// console.log(marker);
// console.log(markerContent);
// const infowindow = new google.maps.InfoWindow({
// content: markerContent,
// });
// console.log(infowindow);
let loading = '<div id="map_loading"></div>';
gd_infowindow.open(jQuery.goMap.map, marker);
gd_infowindow.setContent(loading);
setTimeout(function() {
jQuery(document.body).trigger('geodir_map_infowindow_open', [{
map: 'google',
canvas: map_canvas,
content: markerContent
}]);
}, 100);
}
When the page loads, the local storage items are loaded from marker
and markerContent
, but the following error is shown in the console: Uncaught TypeError: a.get is not a function
. It seems to be triggered by the gd_infowindow
object method. When I comment it out, no errors are displayed, though the code does not function.
The issue seems to be a conflict with the Google Maps JS file loaded from https://maps.googleapis.com/maps/api/js?key=hidden&libraries=places&language=en&ver=2.2.9:300. I have included the supposed conflict code below.
_.Gg.prototype.open=function(a,b){var c=b;b={};"object"!==typeof a||!a||a instanceof _.zg||a instanceof _.lf?(b.map=a,b.anchor=c):(b.map=a.map,b.shouldFocus=a.shouldFocus,b.anchor=c||a.anchor);a=(a=Bg(b.anchor))&&a.get("map");a=a instanceof _.lf||a instanceof _.zg;b.map||a||console.warn("InfoWindow.open() was called without an associated Map or StreetViewPanorama instance.");var d=_.u(Object,"assign").call(Object,{},b);a=d.map;b=d.anchor;c=this.set;var e=d.map;var f=d.shouldFocus;e="boolean"===typeof f?
I am quite new to using Google Maps with this WordPress plugin, so I am unsure of why the infowindow is not executing correctly. It does work outside of the loadUserMarker
function when run through the create_marker
function. The full create_marker
function is included below.
function create_marker(item, map_canvas) {
if (window.gdMaps == 'osm') {
return create_marker_osm(item, map_canvas);
}
var map_options = eval(map_canvas);
jQuery("#" map_canvas).goMap();
gd_infowindow = (typeof google !== 'undefined' && typeof google.maps !== 'undefined') ? new google.maps.InfoWindow({
maxWidth: 200
}) : null;
if (item.lt && item.ln) {
var marker_id, title, icon, cs;
marker_id = item['m'];
title = geodir_htmlEscape(item['t']);
cs = item['cs'];
icon = item['icon'] ? item['icon'] : geodir_params.default_marker_icon;
iconW = item['w'] ? parseFloat(item['w']) : 0;
iconH = item['h'] ? parseFloat(item['h']) : 0;
iconMW = geodir_params.marker_max_width ? parseFloat(geodir_params.marker_max_width) : 0;
iconMH = geodir_params.marker_max_height ? parseFloat(geodir_params.marker_max_height) : 0;
/* Some svg files has dimensions with different unit */
if (geodir_params.resize_marker && ( iconW < iconMW || iconH < iconMH ) && icon.substr((icon.lastIndexOf('.') 1)).toLowerCase() == 'svg') {
iconW = iconW * 10;
iconH = iconH * 10;
}
if (geodir_params.resize_marker && iconW > 5 && iconH > 5 && ((iconMW > 5 && iconW > iconMW) || (iconMH > 5 && iconH > iconMH))) {
resizeW = iconW;
resizeH = iconH;
resize = false;
if (iconMH > 5 && resizeH > iconMH) {
_resizeH = iconMH;
_resizeW = Math.round(((_resizeH * resizeW) / resizeH) * 10) / 10;
resizeW = _resizeW;
resizeH = _resizeH;
resize = true;
}
if (iconMW > 5 && resizeW > iconMW) {
_resizeW = iconMW;
_resizeH = Math.round(((_resizeW * resizeH) / resizeW) * 10) / 10;
resizeW = _resizeW;
resizeH = _resizeH;
resize = true;
}
if (resize && resizeW > 5 && resizeH > 5) {
icon = {
url: icon,
scaledSize: new google.maps.Size(resizeW, resizeH),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point((Math.round(resizeW / 2)), resizeH)
};
}
}
var latlng = new google.maps.LatLng(item.lt, item.ln);
var marker = jQuery.goMap.createMarker({
id: marker_id,
title: title,
position: latlng,
visible: true,
clickable: true,
icon: icon,
label: cs,
zIndex: (item.zIndex ? item.zIndex : 0),
zIndexOrg: (item.zIndexOrg ? item.zIndexOrg : 0)
});
bounds.extend(latlng);
// Adding a click event to the marker
google.maps.event.addListener(marker, 'spider_click', function() { // 'click' => normal, 'spider_click' => Overlapping Marker Spiderfier
var marker_url = map_options.map_marker_ajax_url;
is_zooming = true;
jQuery("#" map_canvas).goMap();
var preview_query_str = '';
if (item.post_preview) {
preview_query_str = '&post_preview=' item.post_preview;
}
marker_url = marker_url '' item.m;
post_data = marker_url.indexOf('?') === -1 ? '?' : '&';
post_data = '_wpnonce=' map_options._wpnonce;
if (map_options.bubble_size) {
post_data = '&small=1';
}
if (map_options.map_marker_url_params) {
post_data = map_options.map_marker_url_params;
}
var loading = '<div id="map_loading"></div>';
gd_infowindow.open(jQuery.goMap.map, marker);
gd_infowindow.setContent(loading);
jQuery.ajax({
type: "GET",
url: marker_url post_data,
cache: false,
dataType: "json",
error: function(xhr, error) {
alert(error);
},
success: function(response) {
jQuery("#" map_canvas).goMap();
html = typeof response == 'object' && response.html ? geodir_htmlEscape(response.html) : '';
gd_infowindow.setContent(html);
gd_infowindow.open(jQuery.goMap.map, marker);
setTimeout(function() {
jQuery(document.body).trigger('geodir_map_infowindow_open', [{
map: 'google',
canvas: map_canvas,
content: html
}]);
}, 100);
/** Custom code begin **/
storeUserMarker(marker, html);
/** Custom code end **/
// give the map 1 second to reposition before allowing it to reload
setTimeout(function() {
is_zooming = false;
}, 1000);
}
});
return;
});
// Overlapping Marker Spiderfier
jQuery.goMap.oms.addMarker(marker);
// Adding a visible_changed event to the marker
google.maps.event.addListener(marker, 'visible_changed', function() {
gd_infowindow.close(jQuery.goMap.map, marker);
});
return true;
} else {
//no lat & long, return no marker
return false;
}
}
Any help is greatly appreciated.
CodePudding user response:
The issue is that you are trying to use plain old JavaScript objects (POJOs) not a google.maps.Marker
, google.maps.Point
, etc. here...
gd_infowindow.open(jQuery.goMap.map, marker);
Where maker is a POJO...
let marker = {
id: markerId,
title: markerTitle,
icon: markerIcon,
anchorPoint: markerAnchor,
position: markerPosition,
visible: true,
clickable: true
};
To fix you will need to create an actual marker/position, etc - e.g. the marker needs to something like...
let marker = jQuery.goMap.createMarker({
id: markerId,
title: markerTitle,
icon: markerIcon, // this will need to be a google.maps.icon too I presume
anchorPoint: new google.maps.Point(anchor.x, anchor.y), // or something
position: new google.maps.LatLng(position.lat, position.lng), // or something
visible: true,
clickable: true
});
However it isn't clear what format you store your "markerPosition", "markerIcon", etc in - but you should probably store values ("latitude", "longitude", "x", "y", "imageUrl", etc) separately so that you can recreate the google.map.whatever
objects when needed.
The key thing here is you need to serialise to store - then deserialize back to actual google.map.whatever
objects to use them.
The error Uncaught TypeError: a.get is not a function
is simply because your marker
is a POJO not a google.maps.Marker