Twitter: raymondcamden


Address: Lafayette, LA, USA

jQuery Tabs and Google Maps

06-05-2009 18,947 views jQuery 7 Comments

A reader wrote in earlier this week about an issue with Google Maps and jQuery tabs. He was trying to use a Google Map in one tab but the map wasn't rendering correctly. Here is a quick example showing what went wrong.

First, a simple HTML page with tabs and a map in the third tab:

view plain print about
1<html xmlns="http://www.w3.org/1999/xhtml">
2<head>
3<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5<title>Untitled Document</title>
6<link type="text/css" rel="stylesheet" href="theme/ui.all.css" />
7
8<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=abcdefg&sensor=false"
9 type="text/javascript">
</script>
10
11<script src="jquery-1.3.1.js"></script>
12<script src="jquery-ui-personalized-1.6rc6.js"></script>
13<script>
14var map
15
16$(document).ready(function() {
17
18    $("#example").tabs();        
19
20    if (GBrowserIsCompatible()) {
21 map = new GMap2(document.getElementById("third-tab"));
22        map.setCenter(new GLatLng(-34.397,150.644), 13)
23 }
24
25});
26</script>
27</head>
28
29<body>
30    
31<div id="example" style="width:600;height:250">
32 <ul>
33 <li><a href="#first-tab"><span>Content 1</span></a></li>
34 <li><a href="#second-tab"><span>Content 2</span></a></li>
35 <li><a href="#third-tab"><span>Content 3</span></a></li>
36 </ul>
37    
38     <div id="first-tab">
39     This is the first tab.
40     </div>
41
42     <div id="second-tab">
43     This is the second tab.
44     </div>
45
46     <div id="third-tab">
47     </div>
48
49</div>
50
51</body>
52</html>

I've blogged about jQuery tabs before (check the official docs for more information), so the only thing new here for my readers would be the Google Maps code. This was the first time I had ever played with them, so I went with their simplest example possible. (Actually, I did it on a page by itself first so I could see it working without the tabs.) Like all things Google, the API is incredibly powerful and complex to use. When run though, the problem is pretty evident:

Notice how the map doesn't fill the tab? The Tabs docs actually cover this issue a bit, but the advice they give doesn't work with the latest Google Maps API. Specifically they suggest the resizeMap() method which isn't a valid call. This led me to dig around some more and find there was something similar: checkResize().

I used the code from the jQuery site to execute when the 3rd tag was selected:

view plain print about
1$('#example').bind('tabsshow', function(event, ui) {
2 if (ui.panel.id == "third-tab") {
3 map.checkResize()
4 }
5})

Unfortunately, this produced the same result. Then it occured to me - what if the map was resizing to some DIV/SPAN/whatever that jQuery Tabs created and the height wasn't the same as what I was seeing. On a whim I tried:

view plain print about
1$('#example').bind('tabsshow', function(event, ui) {
2 if (ui.panel.id == "third-tab") {
3    $(ui.panel).css("height","100%")
4 map.checkResize()
5 }
6})

This was close... but not exactly right:

It kinda looks like the 100% is referring to the complete tab (content and the header), but not quite exactly. I kept playing around and finally ended up with a hard coded exact number, 170. That seemed to work ok:

Obviously this involved a lot of grunt work and reloading, and obviously if you change the height of the main tab div you would have to change the number.

If I can make it run a bit better I'll let folks know.

7 Comments

  • Commented on 06-06-2009 at 12:01 AM
    I had a similar problem with spry tabs. What I found was that according to the map api docs the div tag the map loads in has to be displayed when the map is called. Since the second tab is in a display:none state the div loads weird. I worked around it by calling the map after the tab is revealed. It's also has the added benefit of not pulling the map unless it's viewed. Example: http://www.beckysrealestate.com/3911989/
  • Commented on 06-06-2009 at 8:48 AM
    I believe you are correct. However, even I create the map when the tab is selected, it still doesn't size 'right' height wise. I put "right" in quotes because, again, it does fill the tab div, which is oddly not as tall as the containing tabs.

    As an example, if I use code to set the tab panel to red, you can see the red doesn't fill the entire div.
  • Greg Johnston #
    Commented on 07-31-2009 at 4:39 PM
    Just as a note--it saves a lot of reloading, helps with inspection, etc. if you use Firebug, a great extension for Firefox.
  • Commented on 01-15-2010 at 6:15 AM
    Thanks- currently working on a Bing map solution and ran into the same problem. I didn't actually need to do the .Resize() call. However, I needed to add
    $("#liveMap").css("height","100%") after the map was loaded for it to render correctly.

    Thanks!
  • Vaughn #
    Commented on 03-24-2010 at 7:19 AM
    The answer is actually in the jQuery docs, though it could be a little more explicit:

    http://docs.jquery.com/UI/Tabs

    First, be sure that the code that initializes your map is called BEFORE the snippet that initializes your tabs.

    Second -- and while this may not be necessary, it worked for me -- bind the trigger to the main tabs div before you initialize it.

    Third, be sure that the resizeMap() call is attached to the map opject you created first, e.g., map.resizeMap().

    The only annoyances I had were that the call to resizeMap() makes the browser jump to focus on the map and that it broke out of the default border that jQuery puts around the main tabs container. I couldn't seem to account for the jumping, but a simple border-size: 0 took care of the second.

    Good luck!
  • Commented on 08-11-2011 at 11:33 AM
    Mi solucion que fue testiada y funciona ver mas en el siguiente link.

    http://stackoverflow.com/questions/6344059/how-to-...
  • Commented on 08-11-2011 at 11:33 AM
    Um, in English that is.... ? :)

Post Reply

Please refrain from posting large blocks of code as a comment. Use Pastebin or Gists instead. Text wrapped in asterisks (*) will be bold and text wrapped in underscores (_) will be italicized.

Leave this field empty