1

Update: I have discovered a solution to this problem - please see comments at end of this post.

Original Post: I can't get a Google map (API 3) to show in a view page in Ruby on Rails 3. I'm trying to do this directly, rather than using the GM4R gem, so most of the replies on Stack Overflow I've seen don't apply to my situation. I've succeeded in creating a map on a static page, but not on a model's view page. My code is organized as follows:

application.js (in apps/assets/javascripts):

...
//= require jquery
//= require jquery_ujs
//= require_tree .

googlemaps.js (top level of apps/assets/javascripts):

var map, marker, current_pos, initial_pos = new google.maps.LatLng(49.2649, -123.2351);

function updatePositionDisplay( latlng ) // updates the readout under the map with the supplied position
    {
       document.getElementById('event_latitude').value  = latlng.lat();
       document.getElementById('event_longitude').value = latlng.lng();
    }

function initializemap()
  {
    var mapOptions = { zoom: 14, center: initial_pos, mapTypeId: google.maps.MapTypeId.ROADMAP };
    if (document.getElementById('event_map'))
    { alert( 'There is a map')}
      else {alert('There is no map')}
    map = new google.maps.Map(document.getElementById('event_map'), mapOptions);
    if (map != null) {alert('Map object has been created')}

    updatePositionDisplay( initial_pos );
  }

google.maps.event.addDomListener(window, 'load', initializemap);

events/new.html.erb:

<h1>Create New Event:</h1>

<!-- Display map-->
<div id="event_map" style="width: 80%; height: 60%;"></div>

<%= render 'form' %>

<%= link_to 'Back', events_path %>

events/_form.html.erb (standard - as generated by scaffold):

<%= form_for(@event) do |f| %>
  <% if @event.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@event.errors.count, "error") %> prohibited this event from being saved:</h2>

      <ul>
      <% @event.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :user_id %><br />
    <%= f.number_field :user_id %>
  </div>
  <div class="field">
    <%= f.label :latitude %><br />
    <%= f.text_field :latitude %>
  </div>
  <div class="field">
    <%= f.label :longitude %><br />
    <%= f.text_field :longitude %>
  </div>
  <div class="field">
    <%= f.label :startdatetime %><br />
    <%= f.datetime_select :startdatetime %>
  </div>
  <div class="field">
    <%= f.label :enddatetime %><br />
    <%= f.datetime_select :enddatetime %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Summary of behaviour and problem:

What I am hoping will happen when I call events/new is that I will see a map, followed by a form. I have verified (by inserting alert() calls) that the initializemap function gets called and that the map object is not null (ie, it gets created). Furthermore, the latitude and longitude boxes in the form get properly filled out, showing that the updatePositionDisplay code gets called correctly. However, no map appears.

I am very puzzled by this, because I started this project by writing a static page controller that did render the map properly.

The rendered code on the page looks like the following:

<!DOCTYPE html>
<html>
<head>
  <title>MapApp Prototype</title>
  <!--For alternatives to loading external scripts on all pages, visit: http://railsapps.github.com/rails-javascript-include-external.html-->
  <script src="http://maps.googleapis.com/maps/api/js?sensor=false" type="text/javascript"></script>
  <link href="/assets/application.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/checkins.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/events.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/scaffolds.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/static_pages.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/users.css?body=1" media="all" rel="stylesheet" type="text/css" />
  <script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/checkins.js?body=1" type="text/javascript"></script>
<script src="/assets/events.js?body=1" type="text/javascript"></script>
<script src="/assets/googlemaps.js?body=1" type="text/javascript"></script>
<script src="/assets/static_pages.js?body=1" type="text/javascript"></script>
<script src="/assets/users.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
  <meta content="authenticity_token" name="csrf-param" />
<meta content="SRh+VoCjXu3+LGmiH91+AByrXyNGEzv0nTXuZKbzfS8=" name="csrf-token" />
</head>
<body>

<h1>Create New Event:</h1>

<!-- Display map-->
<div id="event_map" style="width: 80%; height: 60%;"></div>

<form accept-charset="UTF-8" action="/events" class="new_event" id="new_event" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="SRh+VoCjXu3+LGmiH91+AByrXyNGEzv0nTXuZKbzfS8=" /></div>

... (details of form omitted)

</div>
  <div class="actions">
    <input name="commit" type="submit" value="Create Event" />
  </div>
</form>

<a href="/events">Back</a>

</body>
</html>

This all looks correct to me. Any insight or suggestions as to either what I'm doing wrong or what's different between a static page and a model-linked view page would be most welcome.

Update: So it appears that there has to be an explicit styling for the event_map div. I added the following code to app/assets/stylesheets/events.css.scss:

#event_map { height: 300px; }

and that makes it work. However, interestingly, I don't seem to be able to change this to percent notation. If I make it {height: 50%}, I again get a blank map. Any ideas why this is so? I'd prefer to generate a flexible layout with the space allocated to the map being automatically adjusted to the user's browser window size.

ajh
  • 21
  • 1
  • 6
  • did you remove the other inline styling elements? in your html page for `event_map` id? as I see that it has width, height set in % – uday Apr 01 '13 at 21:58
  • Yes, I removed the inline elements on new.html.erb (now reads
    ), so that the only styling is in the .css file. Having height: 300px works, but height: 50% doesn't. Any insight would be hugely appreciated!
    – ajh Apr 01 '13 at 22:02
  • Just tried shifting the styling to inline - as long as I leave #event_map {} in the .css file and use height: 300px, it's fine, but I can't use % with the height specifier without losing the map display. However, in my static page implementation, there's no problem using % (there I use:
    ).
    – ajh Apr 01 '13 at 22:09
  • btw welcome to SO!. see these links to know how the % height works: http://stackoverflow.com/questions/5657964/css-percentage-height, http://stackoverflow.com/questions/1622027/percentage-height-html-5-css – uday Apr 01 '13 at 22:18
  • Thanks! Most questions seem to beget others - in this case, I hadn't yet planned to start wrestling with the CSS, but found I couldn't avoid it, so I appreciate the direction. Anyway, I solved the problem by adding: html, body { height: 100% } on the line before the #event_map directive. All works as expected. Thanks for the prompt help! – ajh Apr 01 '13 at 23:14

0 Answers0