-1

I have this simplified code that creates a google map and allows me to inject text into map InfoWindow bubble.

But here is the problem. Currently the task of function fnGetNewTextForInfoWindow() is trivial. However if I change content of fnGetNewTextForInfoWindow() to call an jquery .ajax query which takes several hundred milliseconds. This results in data coming in late. I think a need a "closure" function but am having trouble keeping context of where function is being called. Guidance needed. Thanks

<!DOCTYPE html>
<html>
<head>

<style>
#map-canvas, #side-bar {        
    height: 500px;
    width: 600px;        
}

</style>

<script src="http://maps.googleapis.com/maps/api/js" type="text/javascript"></script>           
<script src="jquery.js" type="text/javascript"></script> 
<script type="text/javascript">

//  "use strict";

    // variable to hold a map
    var map;

    // variable to hold current active InfoWindow
    var activeInfoWindow ;      

    // ------------------------------------------------------------------ //
    // initialize function      
    // ------------------------------------------------------------------ //
      function initialize() {

        // map options  
        var mapOptions = {
          zoom : 10,
          draggable: true,
          center : new google.maps.LatLng(44.9600, -93.1000),
          mapTypeId : google.maps.MapTypeId.ROADMAP
        };

        // create map in div called map-canvas using map options defined above
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

        // define two Google Map LatLng objects representing geographic points
        var stPaul          = new google.maps.LatLng(44.9522,-93.0892);
        var minneapolis     = new google.maps.LatLng(44.9792,-93.2662);

        // place two markers
        fnPlaceMarkers(stPaul,"St Paul");
        fnPlaceMarkers(minneapolis,"Minneapolis");          
      }

    // -------------------------------------------------------------- //
    // create markers on the map
    // ------------------------------------------------------------- //
    function fnPlaceMarkers(myLocation,myCityName){

        var marker = new google.maps.Marker({
            position : myLocation
        });

        // Renders the marker on the specified map
        marker.setMap(map); 

        // create an InfoWindow
        var infoWnd = new google.maps.InfoWindow();         

        // add content to your InfoWindow
        infoWnd.setContent('<div class="scrollFix">' + 'Welcome to ' +  myCityName + '</div>');

        // add listener on InfoWindow - close last infoWindow  before opening new one 
        google.maps.event.addListener(marker, 'click', function() {

        //Close active window if exists - [one might expect this to be default behaviour no?]               
        if(activeInfoWindow != null) activeInfoWindow.close();

        // get latest text
        var newText = fnGetNewTextForInfoWindow();
        infoWnd.setContent(newText);

        // Open InfoWindow
        infoWnd.open(map, marker, newText);

        // Store new open InfoWindow in global variable
        activeInfoWindow = infoWnd;
    });                             
            }

    function fnGetNewTextForInfoWindow(){
        var newText = $('#idSomeNewText').val();
        return newText;
    }

    // ---------------------------------------------------------- //
    // initial load
    // -----------------------------------------------------------//       
    google.maps.event.addDomListener(window, 'load', initialize);
</script>

Enter Some text to insert in marker:
    <input id='idSomeNewText' type="text" name="firstname" value="test value">  
<br/>  <br/>  
    <div id="map-canvas"></div>

<br/>
<br/>

</body>
</html>

----- added: fnGetNewTextForInfoWindow() would look something like this...

function fnGetNewTextForInfoWindow() {
    $.ajax({
        type: "POST",
        dataType : 'json',
        data: { key1: "value"} ,                
        url: "myProgram",       
        success: function(data) {           
            // I need this value to display in infoWindow
            var newText =  new google.maps.LatLng(markerData[i]['newStatus'],  markerData[i]['newOwner']);
        },  // end success
        error: function (jqXHR, textStatus, errorThrown) { 
            // something bad happened
        }
    });  // end ajax
};

--------- edit - revisions as per Mouser

// -------------------------------------------------------------- //
    // create markers on the map
    // ------------------------------------------------------------- //
    function fnPlaceMarkers(myLocation,myCityName){

        var marker = new google.maps.Marker({
            position : myLocation
        });

        // Renders the marker on the specified map
        marker.setMap(map); 

        // create an InfoWindow
        var infoWnd = new google.maps.InfoWindow();         

        // add content to your InfoWindow
        infoWnd.setContent('<div class="scrollFix">' + 'Welcome to ' +  myCityName + '</div>');

        // add listener on InfoWindow - close last infoWindow  before opening new one 
        google.maps.event.addListener(marker, 'click', function() {

        //Close active window if exists - [one might expect this to be default behaviour no?]               
        if(activeInfoWindow != null) activeInfoWindow.close();

        // get latest text
        // var newText = fnGetNewTextForInfoWindow();
        // infoWnd.setContent(newText);

         // pass infoWnd
         fnGetNewTextForInfoWindow(infoWnd);

        // Open InfoWindow
        // infoWnd.open(map, marker, newText);

        // Store new open InfoWindow in global variable
        //activeInfoWindow = infoWnd;
    });                             

}

    // ---------------------------------------------------------- //
    // 
    // -----------------------------------------------------------//       

    function fnGetNewTextForInfoWindow(infoWindow){
    var infoWnd = infoWindow
    //$.ajax( "data.xml" )
    $.ajax( "example.php" )
    .done(function(data) {
         var newText = data;                    // data from the jQuery ajax call
         infoWnd.setContent(newText);           // set the content
         infoWnd.open(map, marker, newText);    // 
        })
    }
Mustapha George
  • 2,497
  • 9
  • 47
  • 79
  • http://api.jquery.com/jquery.ajax/ read about the `done` and `fail` method on the ajax call. Also post the code with the Ajax call. – Mouser Mar 08 '15 at 14:52

1 Answers1

0

If you have an jQuery Ajax call (you need to fill it up your self). This is just an elementary (basic) Ajax call:

function fnGetNewTextForInfoWindow(infoWindow){
    var infoWnd = infoWindow
    $.ajax( "example.php" )
    .done(function(data) {
         var newText = data; //data from the jQuery ajax call
         infoWnd.setContent(newText);  //set the content
         infoWnd.open(map, marker, newText);
    })
}

To invoke your call replace these lines:

    var newText = fnGetNewTextForInfoWindow();
    infoWnd.setContent(newText);

With

    fnGetNewTextForInfoWindow(infoWnd);

This works by sending the object infoWnd to the fnGetNewTextForInfoWindow function. We set up the Ajax call in the same scope, so we can reuse the infoWnd object in the done method.

Mouser
  • 13,132
  • 3
  • 28
  • 54
  • Thanks for quick reply! I feel a scoping headache coming on here. newText is local to fnPlaceMarkers. I pass infoWnd to another function and act on it. How does it get home safely? By "Ajax call in the same scope", you mean function fnGetNewTextForInfoWindow within the fnPlaceMarkers function? – Mustapha George Mar 08 '15 at 15:15
  • @MustaphaGeorge. Just run every code that's dependent on the `newText` inside that `done` method. Should work perfectly. It never gets home anymore. If you use ajax it will move to another thread, while the main thread continues. How you envision it is like getting out of a train in the station, buy a coffee, drink it and expect the train to be there when you return, however the train moved on. The Ajax call is a new train, however while they are both on the same station luggage can be transferred between them. – Mouser Mar 08 '15 at 15:20
  • made edits as described. I see what you are trying to do, but still not there. I will read documentation........ Here is interesting related thread http://stackoverflow.com/questions/10931836/should-i-use-done-and-fail-for-new-jquery-ajax-code-instead-of-success-and – Mustapha George Mar 08 '15 at 15:59
  • @MustaphaGeorge, saw the edits, the look promising. Reading up on the specs is a good idea. I knew `success` and `error` are going to be phased out so already promoting the correct new way. – Mouser Mar 08 '15 at 16:17
  • still not resolved, if anyone wants to venture opinion. – Mustapha George Mar 08 '15 at 21:28