Google maps - jQuery - Php integration check - javascript

I am constructing a pretty massive website that is WP powered , but uses Google maps as a main interface .
I have a page on the admin side, where I want to be bale to select a location by dragging a marker , and then save this data to MySQL (via Php/wp functions)
Problem is - as much as my WP and PHP foundations are pretty solid , my JS or Jquery are quite basic, not to say shaky .
I have "hacked" together a code from reading the Google maps API, tutoials, and examples -
It produces the map correctly, and also the marker to be dragged , and then it passes the value of [Lat,Lng] to a TXT input via jQuery - which then is saved to the DB.
Everything works fine - except for one issue :
when I edit or save the data - the next time I will open this "post" - there is no marker ,and I need to make a new one and save again .
when I tried to get the Values of the input field with simple
var LatPoint = jQuery('[name=LatTxt]').val()
and
placeMarker(new google.maps.LatLng(LatPoint,LngPoint));
the map failed to generate at all.
The second is that the drag marker function does not update the input.
the third (and not less important) is that I KNOW that the code is horrible, and I am SURE there is a better way to achieve this - and whis whole website purpose is also for me to LEARN - I would like someone to revise the code and advise on how to optimize it ..
this is the code I have up to now ..
var map;
var markersArray = [];// to be used later to clear overlay array
jQuery(document).ready(function(){
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_2k"), myOptions);
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
var marker;
//Function to extract longitude
function placeMarker(location) {
if ( marker ) {
marker.setPosition(location);
} else {
marker = new google.maps.Marker({
position: location,
draggable: true,
title: 'Drag me',
map: map
});
markersArray.push(marker); // to be used later to clear overlay array
}
}
// Removes the overlays from the map, but keeps them in the array
function clearOverlays() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
}
}
//Jquery update HTML input boxes
function updatelonlat() {
jQuery('#LatTxt').val(marker.getPosition().lat());
jQuery('#LonTxt').val(marker.getPosition().lng());
}
// add event click
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
updatelonlat();
//var lat = parseFloat(document.getElementById('LatTxt').value); - somehow not working
});
//google.maps.event.addListener(marker, 'dragend', function(event) {
//document.getElementById("#LatTxt").value = event.latLng.lat(); - somehow not working
map.setCenter(location);
});
Any help would be greatly appreciated ..
EDIT I
I have set up a JSFIDDLE : http://jsfiddle.net/obmerk99/fSj9F/1/
Obviously I can not simulate the PHP function - but it is not needed .
What I want is when the page loads /refresh / save - it will start with a CENTER and a MARKER with vaalues from the input box...
Also - I just now noticed that the drag action is also not updating , I do not know if it is jsfiddle - or my function ...

I've fixed your code in JSFiddle: http://jsfiddle.net/fSj9F/2/
The problems was:
1) You didn't read the values of your inputs before creating the map, and setting the center.
2) You tried to use map.setCenter(location), but the location variable wasn't set
3) You never called your placeMarker function, so the marker was never placed, before the user clicked the map
4) Even though you didn't use the clearOverlays function, I replaced the for..in loop with a regular for. This way you don't iterate the properties of the array (which isn't just the elements, but also the methods of the Array object), but instead you only iterate over the elements contained in the array.
Notice that your code might've been easier to read if you'd declared your functions out of the "ready" function, and if you didn't use global variables such as marker.

Related

Adding Google Maps Marker in localStorage

Is there a way to add a marker created by a user to localStorage? I would like the retrieve the same coordinates of the marker that was added by the user if the browser refreshes or closes. It seems like localStorage can help achieve that.
I am trying something as follows, which doesn't seem correct. Please note that I am fairly new to JavaScript.
google.maps.event.addListener(marker, "dragend", function() {
localStorage.setItem('marker',true);
localStorage.getItem('marker');
});
I think it may be setting the marker in localStorage, but I can't see it upon page refresh.
Thank you.
If you try to store the marker itself you will get an error "Converting circular structure to JSON", even after stringifying it. Plus, it will store extra data which you may not need. I recommend you to store in the browser as minimum as possible of data due to space limitations.
What you can do instead is create your datatype to holds the info of marker (lat and long) and store this object. See the following....
var latlng = new google.maps.LatLng(42.123456789, -36.123456789);
var marker = new google.maps.Marker({
position: latlng
});
var newMarker = {Lat: marker.position.lat(), Lng: marker.position.lng()};
localStorage["marker1"] = JSON.stringify(newMarker);
console.log(localStorage["marker1"]);
play with it here: http://jsfiddle.net/94qhJ/

JavaScript, Maps API: Click one of many elements, extract a portion of its name, and apply it in a function

Forgive me if I misuse any technical terms; I'm still fairly new to programming. I'm creating a map with Google Maps API 3.12 that will include a menu of 600 entries with addresses, but this is mostly a JavaScript issue. Each address is clickable (in a menu) that will cause the map to go to its respective marker. Alternately, clicking a marker will send users to that place in the menu.
I started just going through and writing each out, but I've quickly realize this will send my code well over 20,000 lines, which will both slow my code and be torturous for me.
Here is some of the initial code:
function initialize() {
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var latlng1 = new google.maps.LatLng(41.88267,-87.623758); //etc for all 600 addresses
var marker1 = new google.maps.Marker({
position: latlng1,
map: map
}); //etc for all 600 markers
var contentString1 = '<div>blahblahblah</div>'; //gives content specific to place1.
var infowindow = new google.maps.InfoWindow();
}
The following is where I'd like to save on lines. Instead of copying and pasting this entire code 600 times for place/marker/contentString1 and 2 and 3, up to 600, I'm trying to figure out a way to write this function once for all of them:
google.maps.event.addDomListener(document.getElementById("place1"), "click", function() {
map.setCenter(marker1.getPosition());
map.setZoom(15);
infowindow.setContent(contentString1);
infowindow.open(map, marker1);
window.location = '#map-canvas';
});
This code makes it so I can click on the menu, and the map will jump to the corresponding marker and also pop up an info window. It is always just, "click placeX, go to markerX at latlngX with the respective infowindow content," but I am having the hardest time figuring something out that will be universal.
Could something like the following work? My theory is that clicking on any place in the menu could trigger this function rather than having to click on a specific place. This will then pull out the appending number of the specific place that is clicked (I call that number x below), and apply it to the function below. If I changed the place elements from IDs to class elements, would this make it possible? I'm not even sure how to do it then. Would that in turn create a different problem with the code I already have?
google.maps.event.addDomListener(document.getElementById("place"), "click", function (x) {
map.setCenter("marker" + x.getPosition());
map.setZoom(15);
infowindow.setContent("contentString" + x);
infowindow.open(map, "marker" + x);
window.location = '#map-canvas';
});
I've been trying variations on this for days now, but I can't get anything to work. I'm not sure if it's issues of theory, scope, syntax or all of the above. Any ideas? Thanks.

Custom control to get coordinates from a point in Google API

I'm using JavaScript Google API to build a map for my site (that is going to work for tablets, not for PCs)
I am getting all the markers from the .NET doc;
I want to make a new custom control, and when a user will choose it he will able to click on some point on the map and get the coordinates to a text field.
So I know how to make a new control, and I know how to click on some point in the map and get the coordinates:
When I click I get the lat and long:
google.maps.event.addListener(map, "rightclick", function(event) {
var latFromMap = event.latLng.lat();
var lngFromMap = event.latLng.lng();
// populate yor box/field with lat, lng
document.getElementById("lat").value = latFromMap;
document.getElementById("long").value = lngFromMap;
});
And to make a control (that will take us back to center):
google.maps.event.addDomListener(outer, 'click', function() {
map.setCenter(getcenter)
});
Now. I want to connect them. So only when I click on the control I will be able to check the lat/long in some point.
You may create a new styledMapType as described here (you don't need the styling, simply create the mapType and add it to the controls).
When you do so you have 2 results at once, that you need for your project:
The control, and a property that you can check everytime to determine if the control is active, the mapTypeId
Applying the click would be easy then:
google.maps.event.addListener(map, 'click', function() {
if(this.mapTypeId=='mapTypeIdOfTheStyledMap'){
//execute click-action
}
});
Demo: http://jsfiddle.net/doktormolle/kbXGd/

Opening a second InfoWindow in Google Maps API v3

I'm implementing a Maps interface for a database of music venues and events and have run into an interesting issue. I have a series of HTML elements with onclick calls to a certain Javascript function. The calls run correctly and the javascript function runs correctly the first time (all the information is passed in correctly and my debug alerts display it correctly), and the infoWindow displays. The second time I click on one of these divs, the first one closes correctly, the final alert in the code below fires with the correct information, but the new InfoWindow does not pop up.
Map setup code:
function mapsInitialize() {
var mapOptions = {
center: new google.maps.LatLng(42.4439614, -76.5018807),
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("mapSection"), mapOptions);
google.maps.event.trigger(map, 'resize');
for(var x = 0; x < markers.length; x++){
var tempOptions = {
position: markers[x].position,
title: markers[x].name,
map: map
}
markerObjects[markers[x].title] = new google.maps.Marker(tempOptions);
}
}
Function called onclick from the divs:
function generateInfoWindow(despacedName, despacedTitle, eventTitle, url, date, time){
if(curInfoWindow){
alert("closing " + curInfoWindow.getContent());
curInfoWindow.close();
curInfoWindow = null;
}
curInfoWindow = new google.maps.InfoWindow(options = {size: new google.maps.Size(150,50)});
curInfoWindow.setContent("<a class=\"eventLink\" href=\""+url+"\">"+eventTitle+"</a><br><br>"+markerObjects[despacedName].title+"<br>"+date+" at "+time);
curInfoWindow.open(map, markerObjects[despacedName]);
alert(despacedName+" is "+markerObjects[despacedName]);
}
I can guarantee that the markers[] array is fed correctly.
I have tried, among other things...
Creating an array to hold the infoWindows instead of using one curInfoWindow variable
Not having anything in the array automatically close like the beginning of the generateInfoWindow() function does
Creating the info windows automatically in the mapsInitialize() function
Most of the results on Google when searching for solutions brought me information about event listeners on the map - is that the only way to fire an event like this, or is what I'm trying to do valid?
If any other code examples are needed, let me know. Thanks for any suggestions!
According to Google Maps API:
InfoWindows may be attached to either Marker objects (in which case
their position is based on the marker's location) or on the map itself
at a specified LatLng. If you only want one info window to display at
a time (as is the behavior on Google Maps), you need only create one
info window, which you can reassign to different locations or markers
upon map events (such as user clicks). Unlike behavior in V2 of the
Google Maps API, however, a map may now display multiple InfoWindow
objects if you so choose.
Maybe this would work:
function generateInfoWindow(despacedName, despacedTitle, eventTitle, url, date, time){
if(!curInfoWindow){
curInfoWindow = new google.maps.InfoWindow({maxWidth:150});
}
curInfoWindow.setContent("<a class=\"eventLink\" href=\""+url+"\">"+eventTitle+"</a><br><br>"+markerObjects[despacedName].title+"<br>"+date+" at "+time);
curInfoWindow.open(map, markerObjects[despacedName]);
alert(despacedName+" is "+markerObjects[despacedName]);
}
According to the specs, this should move the existing curInfoWindow to a new marker and update the content.
Note: this code is invalid
new google.maps.InfoWindow(options = {size: new google.maps.Size(150,50)})
There is no size attribute. The best you can do is
new google.maps.InfoWindow({maxWidth:150})
More about InfoWindow API

Anyway to restrict updating a google map when panning

I have a google maps set up with pointers. I've set it up so whenever the zoom changes or the viewport does it loads a new set of pointers accordingly:
google.maps.event.addListener(xmap, 'zoom_changed', function(event){
tm.update();
});
google.maps.event.addListener(xmap, 'bounds_changed', function(event){
tm.update();
});
google.maps.event.addListenerOnce(xmap, 'tilesloaded', function(){
tm.update();
});
I have also set it so that clicking on any pointer would open an infobox that would be populated with data from an ajax query. The problem is that I need to set it up so that if lets say a pointer is to the far edges of the view port it should pan to the center or to a position where when the infowindow opens up it can be viewed in the entire port.
The issue arises is that at times the infowindow when it loads can be too big for the view port and causes the map to pan and that in turn triggers the update function repopulating the pointers again.
WHats the best way to handle this.
So what you could perhaps do is have something like a boolean flag to indicate whether or not to call tm.update(). In your event handler for marker clicks (to open the infowindows), set it to false. Then in your bounds_changed event handler, only call tm.update if that boolean value is true. Then perhaps at the end of bounds_changed, reset it back to true.
Another guess - not to remove and overwrite markers that is already visible (falling into map.getBounds()). When you recive response with new markers to add - verify, if it's not already there.
UPDATE:
After bounds_changed you have new bounds. Then you query your server and get marker coords and other associated data you need. When you adding markers on to the map, save references to them, say, in hash. If you have some unique id - it's perfect. In other case, invent some kind of identifier for marker. Then we need to add new markers and possibly remove some of them, that is hidden. Like this:
// somewhere initially
var markersOnMap = {}
// when got data and adding new markers
markersData = array of markers you've received from request
for (var i=0; i < markersData.length; i++)
{
var datum = markersData[i];
if (typeof(markersOnMap[datum.id]) == 'undefined')
{
// add marker to map
var marker = new google.maps.Marker({
position: ...,
etc.
});
marker.setMap(mymap);
markersOnMap[datum.id] = marker;
}
}
// you may clean up hidden markers or
// leave it for future or what you want.
// suppose we delete out of view markers
for (var id in markersOnMap)
{
if (!mymap.getBounds().contains(markersOnMap[id].getPosition()))
{
// get rid of it
markersOnMap[id].setMap(null);
delete markersOnMap[id];
}
}

Categories

Resources