Search code examples
ruby-on-railsrubyruby-on-rails-3google-maps-api-3rails-geocoder

Show markers on google maps dynamically -Rails 3.2


i have a working code that shows multiple markers on google map using geocoder such as @nearbys = Place.near("#{params[:address]}", 5,:order => "distance",:units => :km) @nearbys.first(5) and i display the markers using the below code

function initialize() {
    var map;
    var bounds = new google.maps.LatLngBounds();
    var mapOptions = {
        mapTypeId: 'roadmap'
    };

    // Display a map on the page
    map = new google.maps.Map(document.getElementById("map-canvas-guest"), mapOptions);
    map.setTilt(45);

    // adding Multiple Markers from ruby object
    var markers = [
        ['<%= @nearbys[0].title %>', '<%= @nearbys[0].latitude %>','<%= @nearbys[0].longitude %>'],
        ['<%= @nearbys[1].title %>', '<%= @nearbys[1].latitude %>','<%= @nearbys[1].longitude %>'],
        ['<%= @nearbys[2].title %>', '<%= @nearbys[2].latitude %>','<%= @nearbys[2].longitude %>'],
        ['<%= @nearbys[3].title %>', '<%= @nearbys[3].latitude %>','<%= @nearbys[3].longitude %>']
        ,
        ['<%= @nearbys[4].title %>', '<%= @nearbys[4].latitude %>','<%= @nearbys[4].longitude %>']
      ];

    // adding Info Window Content 
    var infoWindowContent = [
        ['<div class="info_content" >' +
        '<h3><%= @nearbys[0].title %></h3>' +'</br>'+
        '<p><%= @nearbys[0].about %></p>' +       
         '</div>'],
        ['<div class="info_content">' +
        '<h3><%= @nearbys[1].title %></h3>' +
        '<p><%= @nearbys[1].about %></p>' +
        '</div>'],
                ['<div class="info_content">' +
        '<h3><%= @nearbys[2].title %></h3>' +'</br>'+
        '<p><%= @nearbys[2].about %></p>' +
        '</div>'],
                ['<div class="info_content">' +
        '<h3><%= @nearbys[3].title %></h3>' +'</br>'+
        '<p><%= @nearbys[2].about %>/p>' +
        '</div>'],
                ['<div class="info_content">' +
        '<h3><%= @nearbys[4].title %></h3>' +'</br>'+
        '<p><%= @nearbys[4].about %></p>' +
        '</div>']
    ];

    // Display multiple markers on a map
    var infoWindow = new google.maps.InfoWindow(), marker, i;

    // Loop through our array of markers & place each one on the map  
    for( i = 0; i < markers.length; i++ ) {
        var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
        bounds.extend(position);
        marker = new google.maps.Marker({
            position: position,
            map: map,
            title: markers[i][0]
        });

        // Allow each marker to have an info window    
        google.maps.event.addListener(marker, 'click', (function(marker, i) {
            return function() {
                infoWindow.setContent(infoWindowContent[i][0]);
                infoWindow.open(map, marker);


            }
        })(marker, i));

        // Automatically center the map fitting all markers on the screen
        map.fitBounds(bounds);

    }

    // Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
    var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
        this.setZoom(14);
        google.maps.event.removeListener(boundsListener);
    });

}//initialize ends

BUT the problem is:-what if @nearbys has less than 5 count,then this code fails.SO i have been trying to make it dynamic using jquery arrays but its not working because i think my code is missing something to work it dynamically. it should be something like this..

var array=<%= @nearbys%>;
var markers=[];
var infowindows=[];
array.each(function(index){
markers.push('<%= @nearbys[0].title %>', '<%= @nearbys[0].latitude %>','<%= @nearbys[0].longitude %>');
infowindows.push('<div class="info_content" >'+'<h3><%= @nearbys[0].title %></h3>' +'</br>'+
        '<p><%= @nearbys[0].about %></p>'+'</div>');

})

..SO how i can achieve this........to make this dynamic so that above working code doesnt breaks with the newly added code.


Solution

  • well after struggling with jquery arrays and json ,i was able to find this best solution...this is working in all scenarios and all i need is to handle empty and null conditions,which i already did and its working the way i needed.HOPE THIS HELPS SOMEONE

    my controller

    def show_nearby_locations
    
      @nearbys = Place.near("#{params[:address]}", 5,:order => "distance",:units => :km)
      @nearbys.first(10)
    
    end
    

    in my view file

    <%= javascript_tag do%>
     window.nearbys= <%=raw @nearbys.to_json %>;
    
    <%end%>
    

    this is my script inside view

    function initialize() {
        var map;
        var bounds = new google.maps.LatLngBounds();
        var mapOptions = {
            mapTypeId: 'roadmap'
        };
    
        // Display a map on the page
        map = new google.maps.Map(document.getElementById("map-canvas-guest"), mapOptions);
        map.setTilt(45);            
    
        var markers=[];
        var infoWindowContent=[];
        $.each(nearbys, function(index) { 
    
            console.log( data[0][index].latitude,data[0][index].longitude );
            markers.push([nearbys[index]['title'], nearbys[index]['latitude'],nearbys[index]['longitude']]);
            infoWindowContent.push(['<div class="info_content" >' +
            '<h3 style="color: rgb(<%= rand(0..200)%>,<%= rand(0..200)%> ,<%= rand(0..200)%>);">'+nearbys[index]['title']+'</h3>' +'</br>'+
            '<p>'+nearbys[index]['about']+'</p>' +       
             '</div>']);
    
            });   
    
           // Display multiple markers on a map
           var infoWindow = new google.maps.InfoWindow(), marker, i;        
          // Loop through our array of markers & place each one on the map  
          for( i = 0; i < markers.length; i++ ) {
              var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
              bounds.extend(position);
              marker = new google.maps.Marker({
                position: position,
                map: map,
                title: markers[i][0]
            });
    
            // Allow each marker to have an info window    
            google.maps.event.addListener(marker, 'click', (function(marker, i) {
                return function() {
                    infoWindow.setContent(infoWindowContent[i][0]);
                    infoWindow.open(map, marker);
    
    
                }
            })(marker, i));
    
            // Automatically center the map fitting all markers on the screen
            map.fitBounds(bounds);
    
        }
    
        // Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
        var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
            this.setZoom(14);
            google.maps.event.removeListener(boundsListener);
        });
    
    }//initialize ends