Running a JS Method on load from code behind - javascript

I am trying to load the following JS method:
<script type="text/javascript">
function initialize(lon,lat) {
var myLatlng = new google.maps.LatLng(lon,lan);
var myOptions = {
zoom: 14,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map
});
}
</script>
In my code behind in VB.NET I then want to load such as:
initialize(53.349803617967446, -6.260257065296173)
I need to load in code behind since I have to get the longtidude and latidude from DB.

An alternative to Chuck's suggestion - you could keep the function in the .aspx and write out those values directly into the Javascript using inline code, like the following:
initialize(<%=strLat%>, <%=strLon%>)
strLat and strLon would be defined as protected variables in your code-behind.
If you really want the whole function to be written out by the code-behind, look into the RegisterClientScriptBlock method.

It's not usually best practice to call Javascript functions directly from the code behind. The code behind is code that happens prior to the page's rendering.
What I would do is add two hidden literals to your page, latitude and longitude, and call your initialize function on the DOM ready event. The initialize function would retrieve the lat/long values from the created literals.
Here is a good resource to learn about the DOM ready event if you're not familiar.
Edit: If the above is not an option, you can "call" it from the code-behind in a rather roundabout way (This is almost functionally equivalent to my other solution).
<body runat="server">
Make your body tag look like that and then add this to the code-behind:
var javascriptFunction = string.format("javascript:initialize({0}, {1})", latValue, longValue);
Body.Attributes.Add("Onload", javascriptFunction);

You can use RegisterClientScriptBlock to insert Javascript into the page from the code-behind.
You would insert it inside whatever function you want to register it from, and format it like this:
ClientScriptManager.RegisterClientScriptBlock(typeof(this), "SomeKeyName", "initialize(" + lat + "," + long + ");", true);
where SomeKeyName is a unique key that prevents the script from being added more than once per postback.

If you must register both the function and the call from the code-behind, you would want to use ScriptManager.RegisterClientScriptBlock for the function, and ScriptManager.RegisterStartupScript for the call to the function. If the rendering of the function is not dependent upon anything from your server code, you would be better off not registering it from code, though.

Related

Meteor templates loading

I've build a simple app with Meteor. It basicly gets locations from database and shows them to user. This is done via webservice. In the template I have a google map. Which gets the coordinates of locations and then displays them on the map. The basic idea works. However, the problem is that my webservice is called when google map loads. Therefore when template map is created (it's created when user selects tab /map and map template is created - or am I wrong?). And because of that when I open my homepage first, the webservice is not called and I don't get the data.
How is this problem solved? I want to load all the data when user opens the app. onRendered and onCreated won't solve this I think. If you know the answer please write it down, if it is obvious please share a link where I can read about it.
Thanks
To solve your issue, you should first create the map (without marker), and when you have the geolocalisation of the user, you will be able to draw it on the map. Or you can wait the user position before rendering the map. All you need is a reactive treatment.
You can store a variable in a ReactiveVar - you just need to add this very interesting package :
meteor add reactive-var
or you can use the meteor Session. I will use the session for the example, it's easier.
Your template.js (that I wrote without testing, comment on this post if you have any issue)
Template.map.onRendered(function() {
// Create an undefined value for this template,
this.marker;
var myLatLng = {lat: -25.363, lng: 131.044};
// Render an empty map
this.map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
// Each time a reactive variable like ReactiveVar or session is edited,
// rerun this function
this.autorun(function() {
// this autorun will rerun each time Session.get("userPosition") is edited
var userPosition = Session.get("userPosition");
if (userPosition && this.marker === undefined) {
this.marker = new google.maps.Marker({
position: myLatLng,
map: this.map,
title: 'Hello user!'
});
}
});
});
Source google map API : https://developers.google.com/maps/documentation/javascript/examples/marker-simple

Embed a Google Map into a dynamically created div

I'm trying to dynamically generate a Google map when the user submits a form, but the map does not appear in its div when the form is submitted.
I tested to see if the map populates on merely on pageload and it does, but when trying to use a div that displays onclick the map does not show.
<form onsubmit="return false" action="">
<input type="text" id="addLocation"/>
<button onclick="findLocation()" id="btnLocation">Find Location</button>
</form>
<div id="mapContainer"></div>
This is the JavaScript:
function findLocation(){
var inputString = $('#addLocation').val();
$('#mapContainer').html('<div id="mapCanvas"></div>');
var apiRequest = $.ajax({
url: 'http://xxxxx.net/json/'+ inputString,
dataType: 'json',
type: 'get',
});
apiRequest.done(function(data){
var lat = data['latitude'];
var lng = data['longitude'];
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(lat, lng),
zoom: 8
};
map = new google.maps.Map(document.getElementById('mapCanvas'), mapOptions);
}
// from GMaps API docs
function loadScript() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp' + '&callback=initialize';
document.body.appendChild(script);
}
window.onload = loadScript;
}); // ends .done statement
} // ends findLocation
It should be that when you click the Find Location button it will generate a map in the mapCanvas div but it does not.
I found out from the Google Maps API documentation that if you want to asynchronously load a map you have to use that loadScript function.
And yes, the map divs have widths and heights in the CSS, so that's not the problem. I think the problem is with the Javascript scopes. I'm doing something wrong with the order or placement of the calls, just not sure what.
First, it is not true that you have to load the Maps API asynchronously when you want to create a map dynamically. You can load the API either using the asynchronous method or with a conventional <script> tag. Loading the API does not create a map; it merely loads the code. A map is not created until you call new google.maps.Map().
So one easy solution would be to go back to a <script> tag to load the API, and simply call your initialize() function directly inside your ajax callback. (Or pull the code out of the initialize() function and just run it inline inside the callback.)
In fact, in your current code you are already loading the Maps API at page load time, with this line:
window.onload = loadScript;
That causes the loadScript() function to be called at page load time.
So you may as well just use a <script> tag to load the API, it's more or less the same thing you're doing now but simpler.
If you do want to load the Maps API dynamically, #sirfriday's comment is correct: your initialize function is not visible in the global scope, and it needs to be so the asynchronous API load can call it when ready.
You mentioned that "calling initialize didn't do it." - but you shouldn't be calling initialize() in this case, you should set window.initialize to be a reference to the function, e.g.:
window.initialize = initialize; // note no () so it doesn't call it here
Or change the function like this:
window.initialize = function() {
...
};
And also if you want to load the API dynamically, don't do it at onload time. Instead, call your loadScript() function inside your ajax callback. That will give you the right sequence of operations:
Page loads
User interacts with it and the ajax request starts
Ajax request completes
Maps API loads
Your initialize() function gets called

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.

Google maps - jQuery - Php integration check

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.

Google Maps - Same text appears in info window when using multiple markers

I'm having an issue with multiple markers on google maps - I currently have a MySQL database storing info (location info). In php I then extract this info and loop through each postcode to dynamically create the required javascript to place a marker for each place in my database.
This works successfully so I know that I'm passing the correct information to the js function - Now what I'm trying to achieve is adding additional information when the marker is clicked but its showing the same on every marker window.
This is the js I'm using (I initiate an icon at the top but excluded this from the code for now):
function usePointFromPostcode(postcode, callbackFunction, text) {
localSearch.setSearchCompleteCallback(null,
function() {
if (localSearch.results[0])
{
var resultLat = localSearch.results[0].lat;
var resultLng = localSearch.results[0].lng;
var point = new GLatLng(resultLat,resultLng);
callbackFunction(point, text);
}else{
alert("Postcode not found!");
}
});
localSearch.execute(postcode + ", UK");
}
function placeMarkerAtPoint(point, html, icon)
{
var marker = new GMarker(point,{icon: icon});
GEvent.addListener(marker,"click",function() {
marker.openInfoWindowHtml(html);
});
map.addOverlay(marker);
}
The php code I have is:
$query = "SELECT * FROM hospitalInfo";
$result = mysql_query($query);
if($result) {
while ($row = mysql_fetch_assoc($result)) {
$code .= "usePointFromPostcode('".$row['Postcode']."', placeMarkerAtPoint,
'".$row['placeName']."');";
}
}
$code is then echo'ed.
Any advice on why this is occuring would be much appreciated! Thanks !
You may be having a scope/closure problem, similar to the issue discussed here.
Try replacing this code:
GEvent.addListener(marker,"click",function() {
marker.openInfoWindowHtml(html);
});
with this:
marker.bindInfoWindowHtml(html);
If that doesn't work, I'd guess that the closure problem is coming from the setSearchCompleteCallback() function. It's difficult to guess without seeing the actual page.
As you mentioned in your comment, the problem is that you're sending several requests before you get any results, and the value of the marker text changes each time you send the request. I think you could greatly simplify your code by using the GClientGeocoder - unless it's absolutely necessary to use GLocalSearch, which isn't really part of the Maps API. Here's Google's tutorial for the geocoder.
First create the geocoder like this:
var geocoder = new GClientGeocoder();
Next, here's your new usePointFromPostcode() function:
function usePointFromPostcode(postcode, text) {
geocoder.getLatLng(postcode, function(point) {
if (!point) {
//alert('address not found');
} else {
var marker = new GMarker(point, {icon: icon});
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(text);
});
map.addOverlay(marker);
}
});
}
This worked great for me. Try it out and let us know how it goes.
If you need more information about the returned point, like accuracy, use getLocations() instead of getLatLng(). The tutorial explains how it works.
I don't see a problem with your Google Maps Code. I suggest you try logging the html parameters in placeMarkerAtPoint and the text param to the localSearch callback. Google have a very useful logging API you could use:
GLog Reference
I would add at the begining of the placeMarkerAtPoint function:
GLog.write ("placeMarkerAtPoint - " + html);
and in the localSearch callback:
GLog.write ("SearchCompleteCallback - " + text);
I think the logging for these two callbacks (particularly the second one), will make it obvious where the html is getting lost.
Update: Ok, based on your logging your PHP code is fine. You are generating three calls to usePointFromPostcode.
The problem here is with your google.search.SearchControl callback. I am assuming the search is working correctly and the results array you get back is appropriate for each respective postcode?
If so, then the problem is with the text parameter in the setSearchCompleteCallback. I haven't used the Google AJAX Search stuff, but the problem lies in how these callbacks are fired. It looks like you can get multiple callbacks for a single execute.
You're re-using the name marker so the last text you place ends up getting attached to all of them. Create an index and name them marker1, marker2, etc. Its easy to do in a php loop.

Categories

Resources