Ajax Call to Map Inside Tabbed Panel

Hi Everyone,

I have a small issue. I want to use tabbed panels for my client’s site so that we only have one page with all content on that one page inside of tabbed panels. That part is easy.

But I want to put a dynamic map inside of one of those panels, but (as we all know) maps don’t work as hidden content. And that’s what tabs are–hidden content. So, is it possible to write a function that will make an ajax call to the map content once the tabbed panel is open and display it at that time?

Or is there another way to tackle that problem?

Thanks!

Can you put an example online?

If you’re using jQuery UI tabs then you can change the .ui-tabs-hide class slightly to accommodate the maps. (Though the principle is the same for other tab solutions.)


.ui-tabs-hide {
  position:absolute;
  left:-9999px;
  display:block; /* to negate the default if it is set somewhere else */
}

It’s been a while since I’ve used a map in tabs, but it ought to still work.

There is also the “activate” event that you can monitor. You could then check if there is a map in the newly activated tab and (re)initialize it.

Hey Denk. I will put an example online probably tomorrow. I had tried it once before and was so frustrated with the outcome that I decided to go another route. But I just wanted to ask, first, to see if this was even plausible. Again, I’ll give you guys something to look at by tomorrow. Thx.

             Code css:
             [FONT=monospace]

.ui-tabs-hide { position:absolute; left:-9999px; display:block; /* to negate the default if it is set somewhere else */ }[/FONT]

Hey AJ, can you tell me in detail how the above works, in theory…?

There is also the “activate” event that you can monitor. You could then check if there is a map in the newly activated tab and (re)initialize it.

And how does the activate event work (practically) with the tabs?

Again, as I told denk, I will put something up tomorrow.

Thanks!

The map doesn’t work when it is hidden (display:none;) - this method gets around that by displaying the panel but hiding it off-screen so that Google Maps can still perform JavaScript operations (like getting/setting the width/height of the map area).

It would be a pretty easy thing to test. In fact, I put together a quick JS Fiddle to demo the difference between hiding off-screen and display:none;

I have 3 tabs set up, tab 2 and 3 have a google map in them. Tabs 1 and 2 are hidden off screen when not active, tab 3 is set to display:none;


.ui-tabs .ui-tabs-hide {
    display: block;
    position: absolute;
    left:-9999px;
}
.ui-tabs #tab3.ui-tabs-hide {
    display: none;
    position: static;
}

The way this method works is that you continue using the traditional method of hiding non-active panels, but you monitor the activate event. In the event handler for activate you will know which panel became active, you can then check inside this panel to see if it contains a map. If it does, you can re-initialize the map so it will show up.

Hey AJ!

Just getting back to work. Forgot to respond while away and didn’t want to appear ungrateful. Thanks for the help on this. It was an excellent lesson! Made huge progress!

No worries! Always nice to hear good feedback :slight_smile:

By the way, John, I am having some strange behavior in my tabs. When I am on the home tab, there appears a HUGE amount of space below my footer. This doesn’t happen when all other tabs are open. Here is URL http://www.galileedetroit.org/index2.php. I cannot figure out the problem. Did this happen when we implemented the JQUI or maps technique? Hate to sound stupid. But just trying to whet the thinking, here. I hope I didn’t include all the code unnecessarily. Thanks in advance!!!

Here is my css


body {
    margin: 0;
    padding: 0;
    font-size: 100%;
    font-family:Arial, Helvetica, sans-serif;
    color: #666;
}

#pageHeader {
    width: 100%;
    padding: 10px 0 10px 0;
    border-bottom: 1px dotted #333;
}

#headerContent {
    width: 1100px;
    height: 75px;
    margin: 0 auto;
    border: 1px dotted #333;
}

#marqueeArea {
    width: 100%;
    padding: 25px 0 25px 0;
    border-bottom: 1px dotted #333;
}

#marquee {
    width: 1100px;
    height: 250px;
    margin: 0 auto;
    border: 1px dotted #333;
}

#auxillaryArea {
    width: 100%;
    padding: 5px 0 5px 0;
    border-bottom: 1px dotted #333;
}

#auxillaryLinks {
    width: 1100px;
    height: 35px;
    margin: 0 auto;
    border: 1px dotted #333;
}

#container {
    width: 100%;
    padding: 15px 0 15px 0;
    border-bottom: 1px dotted #333;
}

#columnWrapper {
    width: 1100px;
    margin: 0 auto;
}

#column1 {
    width: 250px;
    float: left;
    margin-right: 10px;
}

#navigation {
    width: 240px;
    height: 280px;
    margin: 10px 0 10px 0;
    border: 1px dotted #333;
}

#sidebar {
    width: 240px;
    height: 280px;
    margin: 10px 0 10px 0;
    border: 1px dotted #333;
}

#column2 {
    width: 840px;
    float: left;
}

#mainContent {
    width: auto;
    margin: 10px 0 10px 0;
}

#tabbedPanels {
    width: auto;
    margin: 0 auto;
}

#tabs {
    width:auto;
    font-size: 85%;
}

.panel {
    min-height:300px;
    height: 573px;
}

#map {
    width:700px;
    margin:0 auto;
    height:300px;
    border:1px solid #666;
}

.ui-tabs .ui-tabs-hide {
    display: block;
    position: absolute;
    left:-9999px;
}
/*
.ui-tabs #tab10.ui-tabs-hide {
    display: none;
    position: static;
}
*/
#pageFooter {
    width: 100%;
    padding: 10px 0 10px 0;
    border-bottom: 1px dotted #333;
}

#footerContent {
    width: 1100px;
    height: 100px;
    margin: 0 auto;
    border: 1px dotted #333;
}
/*///////////////////////////////////////////// CLEAR FIX BEGIN ///////////////////////////////////////////////////*/

.clearfix:after,.clearfix:after {
    content:"";
    display:table;
}

.clearfix:after {
    clear:both;
}

/*///////////////////////////////////////////// CLEAR FIX END ///////////////////////////////////////////////////////*/


And here is my HTML



<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Galilee Detroit Home</title>
<!--[if lt IE 9]>  
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>  
<![endif]-->
<!--[if lt IE 8]>
    <link href="_css/ie7-and-down.css" rel="stylesheet" type="text/css" media="all">
<![endif]-->
<!--[if IE]>
    <link href="_css/ie.css" rel="stylesheet" type="text/css" media="all">
<![endif]-->
<script type="text/javascript">
document.createElement("article");
document.createElement("section");
document.createElement("address");
document.createElement("footer");
document.createElement("header");
document.createElement("hgroup");
document.createElement("nav");
</script>
<link href="_css/master2.css" rel="stylesheet" type="text/css" media="all" />
<!--
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>window.jQuery || document.write("<script src='_js/jquery-1.8.3.min.js'>\\x3C/script>")</script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
-->
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/smoothness/jquery-ui.css" />
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
$(document).ready(function(){
    $("#tabs").tabs();
    var marker;
    var map;

    var mapOptions = {
        zoom: 15,
        center: new google.maps.LatLng(42.436570, -83.01364),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map'), mapOptions);
    marker = new google.maps.Marker({
        map:map,
        animation: google.maps.Animation.DROP,
        position: location
    });

});
</script>

</head>
<body>
<!-- BEGIN HEADER -->
<header id="pageHeader">
<!-- BEGIN HEADER CONTENT -->
<div id="headerContent">
</div>
<!-- END HEADER CONTENT -->
</header>
<!-- END HEADER -->
<!-- BEGIN MARQUEE AREA -->
<section id="marqueeArea">
<!-- BEGIN MARQUEE -->
<div id="marquee">
</div>
<!-- END MARQUEE -->
</section>
<!-- END MARQUEE AREA -->
<!-- BEGIN AUXILLARY AREA -->
<section id="auxillaryArea">
<!-- BEGIN AUXILLARY LINKS -->
<div id="auxillaryLinks">
</div>
<!-- END AUXILLARY LINKS -->
</section>
<!-- END AUXILLARY AREA -->
<!-- BEGIN CONTAINER -->
<section id="container">
<!-- BEGIN COLUMN WRAPPER -->
<div id="columnWrapper" class="clearfix">
<!-- BEGIN COLUMN 1 -->
<section id="column1">
<!-- BEGIN NAVIGATION -->
<nav id="navigation">
</nav>
<!-- END NAVIGATION -->
<!-- BEGIN SIDEBAR -->
<article id="sidebar">
</article>
<!-- END SIDEBAR -->
</section>
<!-- END COLUMN 1 -->
<!-- BEGIN COLUMN 2 -->
<section id="column2">
<!-- BEGIN MAIN CONTENT -->
<article id="mainContent">
<!-- BEGIN TABBED PANELS -->
<div id="tabbedPanels">
<div id="tabs">
        <ul>
            <li> <a href="#tab1">Home</a></li>
            <li> <a href="#tab2">About</a></li>
            <li> <a href="#tab3">Pastor</a></li>
            <li> <a href="#tab4">Ministries</a></li>
            <li> <a href="#tab5">Prayer</a></li>
            <li> <a href="#tab6">Giving</a></li>
            <li> <a href="#tab7">Store</a></li>
            <li> <a href="#tab8">Calendar</a></li>
            <li> <a href="#tab9">Gallery</a></li>
            <li> <a href="#tab10">Contact</a></li>
        </ul>

        <div class="panel" id="tab1">
            <h1>Home</h1>
        </div>
        
        <div class="panel" id="tab2">
            <h1>About</h1>
        </div>
        
        <div class="panel" id="tab3">
            <h1>Pastor</h1>
        </div>
        
        <div class="panel" id="tab4">
            <h1>Ministries</h1>
        </div>
        
        <div class="panel" id="tab5">
            <h1>Prayer</h1>
        </div>
        
        <div class="panel" id="tab6">
            <h1>Giving</h1>
        </div>
        
        <div class="panel" id="tab7">
            <h1>Store</h1>
        </div>
        
        <div class="panel" id="tab8">
            <h1>Calendar</h1>
        </div>
        
        <div class="panel" id="tab9">
            <h1>Gallery</h1>
        </div>
        
        <div class="panel" id="tab10">
            <h1>Contact</h1>
            <div id="map"></div>
        </div>
    </div>
</div>
<!-- END TABBED PANELS -->
</article>
<!-- END MAIN CONTENT -->
</section>
<!-- END COLUMN 2 -->
</div>
<!-- END COLUMN WRAPPER -->
</section>
<!-- END CONTAINER -->
<!-- BEGIN PAGE FOOTER -->
<footer id="pageFooter">
<!-- BEGIN FOOTER CONTENT -->
<div id="footerContent">
</div>
<!-- END FOOTER CONTENT -->
</footer>
<!-- END PAGE FOOTER -->
</body>
</html>

Thanks again,

G.

The first thing I might get you to try is to put your stylesheet after the jQuery UI stylesheet so that your styles are definitely overwriting theirs.

Next thing would be to also put a “top” property on the ui-tabs-hide style rule:

.ui-tabs .ui-tabs-hide {
    position: absolute;
    left: -9999px;
[COLOR=#ff0000]    top: 0;[/COLOR]
}

Hey AJ,

I found the problem. I actually had to load my style sheet before all the other files.


<link href="_css/master2.css" rel="stylesheet" type="text/css" media="all" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/smoothness/jquery-ui.css" />
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>

Don’t really know what the lesson is here, tho. Can you enlighten me? Also, I am trying like heck to get this marker/bubble to show up on the map and it’s driving me nuts. Do you mind looking at this?


$(document).ready(function(){
    $("#tabs").tabs();
    var marker;
    var map;

    var mapOptions = {
        zoom: 15,
        center: new google.maps.LatLng(42.436570, -83.01364),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map'), mapOptions);
    marker = new google.maps.Marker({
        map:map,
        animation: google.maps.Animation.DROP,
        position: location
    });

});

Thanks so much!

G

Most of the time when you’re loading in framework CSS you want to load it in before your own CSS. That way you override and of the defaults they set without needing to create a more specific CSS rules.

Is the location variable actually being set somewhere? If not, you’ll need to supply a LatLng object, e.g. new google.maps.LatLng(42.436570, -83.01364)


    marker = new google.maps.Marker({
        map:map,
        animation: google.maps.Animation.DROP,
[COLOR=#ff0000]        position: location
[/COLOR]    });

Thanks, AJ. I forgot to define the location variable. Great catch.

Also, I put up a topic about the map “overlay” (or talk bubble) into which I could put HTML, like the address, an image, etc. Although, I don’t think I was as specific as I should have been. Namely, I didn’t call it an overlay. But, the reason I didn’t address it in this thread was because I wanted to establish a new topic just in case someone else needed that specific thing. So far, however, I haven’t gotten a response.

I did some research on my own, but I couldn’t find anything specific to the JQuery framework. I tried to use the Gmarker object, but I screwed it up. I guess because I didn’t know how to implement it in JQuery.

Any advice? If we can work this out, then I will post the answer in the aforementioned thread on that topic.

Thanks again!

G