views:

68

answers:

1

Hi,

I've been using the code from this V3 example to set up a links bar that dynamically populates when different category filters are selected, but have two problems at the moment. Firstly, I've put the the initial makeSidebar function in the map's idle event, but the sidebar is only created when the map is moved, not on loading of the page. Secondly, I can't seem to get the marker infowindow to open when the corresponding link is clicked in the sidebar. My code is below:

var map;
var infowindow;
var image = [];
var gmarkers = [];
var place;
var side_bar_html = "";

  image['attraction'] = 'http://google-maps-icons.googlecode.com/files/beach.png'; 
  image['food'] = 'http://google-maps-icons.googlecode.com/files/restaurant.png';
  image['hotel'] = 'http://google-maps-icons.googlecode.com/files/hotel.png';
  image['city'] = 'http://google-maps-icons.googlecode.com/files/smallcity.png';

function mapInit(){

    var placeLat = jQuery("#placelat").val();
    var placeLng = jQuery("#placelng").val();
    var centerCoord = new google.maps.LatLng(placeLat, placeLng); 

    var mapOptions = {
        zoom: 15,
        center: centerCoord,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(document.getElementById("map"), mapOptions);

    google.maps.event.addListener(map, 'idle', function() {
      var bounds = map.getBounds();
      var ne = bounds.getNorthEast();
      var sw = bounds.getSouthWest();
      var yMaxLat = ne.lat();
      var xMaxLng = ne.lng();
      var yMinLat = sw.lat();
      var xMinLng = sw.lng();
      //alert("bounds changed");
      updateMap(yMaxLat, xMaxLng, yMinLat, xMinLng);
      show("attraction");
      show("food");
      show("hotel");
      show("city");
      makeSidebar();
    });

    function updateMap(yMaxLat, xMaxLng, yMinLat, xMinLng) {
    jQuery.getJSON("/places", { "yMaxLat": yMaxLat, "xMaxLng": xMaxLng, "yMinLat": yMinLat, "xMinLng": xMinLng }, function(json) {
      if (json.length > 0) {
        for (i=0; i<json.length; i++) {
          var place = json[i];
          var category = json[i].tag;
          var name = json[i].name;
          addLocation(place,category,name);
          //makeSidebar();
        }
      }
    });
   }

    function addLocation(place,category,name) {
      var marker = new google.maps.Marker({
        position: new google.maps.LatLng(place.geom.y, place.geom.x),
        map: map,
        title: place.name,
        icon: image[place.tag]
      });
      //var iwNode = document.getElementById("infowindow");

      marker.mycategory = category;
      marker.myname = name;
      gmarkers.push(marker);

      google.maps.event.addListener(marker, 'click', function() {
        if (infowindow) infowindow.close();
        infowindow = new google.maps.InfoWindow({
          content: "<div id='infowindow'><div id='infowindow_name'><p>"+ place.name +"</p></div><div id='infowindow_contents'><p>" + place.tag +"</p><a href='/places/"+place.id+"' id='place_link'>Show more!</a></div></div>"
        });
        infowindow.open(map, marker);
        google.maps.event.addListener(map, 'click', function() {
          infowindow.close();
        });
      });
    }

    function show(category) {
      for (var i=0; i<gmarkers.length; i++) {
        if (gmarkers[i].mycategory == category) {
          gmarkers[i].setVisible(true);
        }
      }
      document.getElementById(category+"box").checked = true;
    }

    function hide(category) {
      for (var i=0; i<gmarkers.length; i++) {
        if (gmarkers[i].mycategory == category) {
          gmarkers[i].setVisible(false);
        }
      }
      document.getElementById(category+"box").checked = false;
      infowindow.close();
    }

    function boxclick(box,category) {
      if (box.checked) {
        show(category);
      } else {
        hide(category);
      }
      makeSidebar();
    }

    jQuery('#attractionbox').click(function() {
      boxclick(this, 'attraction');
    });

    jQuery('#foodbox').click(function() {
      boxclick(this, 'food');
    });

    jQuery('#hotelbox').click(function() {
      boxclick(this, 'hotel');
    });

    jQuery('#citybox').click(function() {
      boxclick(this, 'city');
    });

    function myclick(i) {
      google.maps.event.trigger(gmarkers[i],"click");
    }

    function makeSidebar() {
      //var html = "";
      for (var i=0; i<gmarkers.length; i++) {
        if (gmarkers[i].getVisible()) {
          side_bar_html += '<a href="javascript:myclick(' + i + ')">' + gmarkers[i].myname + '<\/a><br>';
         }
       }
       document.getElementById("side_bar").innerHTML = side_bar_html;
    }
}

jQuery(document).ready(function(){
  mapInit();
  //makeSidebar();
});

Any help would be much appreciated - what can I do to get the sidebar loaded when the page loads, and to get the link click event working? Thanks!

+2  A: 

The reason your links are not working is that you are defining your my_click and makeSidebar functions inside of your mapInit function and so they are not available outside of the scope of mapInit. Simply move them outside of mapInit and everything should just work.

As for the load event ... what you are looking for is the addDomListener method of google.maps.event. Simply use

google.maps.event.addDomListener(window, 'load', name_of_your_inital_function);
// e. g. google.maps.event.addDomListener(window, 'load', mapInit);

Finally; notta bene ... don't do this:

var image = [];
image['attraction'] = 'data'; 
image['food'] = 'more data';

Arrays are not meant to be used as hashes in Javascript. Use objects for dictionaries / hashes instead -- it's what you are actually doing (Array "subclasses" Object) and it will make it easier for others to use your code (and save you from headaches down the line).

var image = {};
image['attraction'] = 'data'; 
image['food'] = 'more data';
Sean Vieira
Let me know if I can do anything else to help.
Sean Vieira
Cheers, that's getting closer to the behaviour I want! BTW: thanks for the heads up about the array :)
Sonia