How to display two gmaps properly
ivanjaros - December 29, 2008 - 21:10
| Project: | Quick Tabs |
| Version: | 6.x-2.0-rc3 |
| Component: | Documentation |
| Category: | task |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Description
I have a module which generates two google map blocks. First map is always displayed properly, but second is always corrupted.
I have to anyhow change the browser window(de-maximize, maximize, resize,...) to dispaly second map as it shoul be displayed. I played with it a little bit and I found that it's caused by the quicktabs module itself. I have ajax turned off, because nothing would display with it enabled, so I assume that the bug is somewhere in the qt "skeleton".
Screenshot -> http://img142.imageshack.us/img142/5403/screenshot002cf3.png
| Attachment | Size |
|---|---|
| ScreenShot002.png | 242.22 KB |
| ScreenShot002.png | 242.22 KB |

#1
Is it your own module? can you share some minimal code to display a google map?
My first guess would be that the javascript used to resize the map background to the size of the available area does not work on hidden HTML elements, as the second tab is hidden at page load.
#2
<?php
function iv_bloky_obsah($typ) {
$clanky = array();// clanky
$zamky = array();// zamky
// query pre clanky
$res_story = db_query("SELECT n.nid, n.title, l.latitude, l.longitude
FROM {node} as n
JOIN {location_instance} as li on li.nid = n.nid
JOIN {location} as l on l.lid = li.lid
WHERE n.status = 1 AND n.type='story'");
// query pre zamky
$res_castle = db_query("SELECT n.nid, n.title, l.latitude, l.longitude, ctc.field_castle_foto_fid, f.filename
FROM {node} as n
JOIN {location_instance} as li on li.nid=n.nid
JOIN {location} as l on l.lid = li.lid
LEFT JOIN {content_type_castle} as ctc on ctc.nid = n.nid
LEFT JOIN {files} as f on f.fid = ctc.field_castle_foto_fid
WHERE n.status = 1 AND n.type = 'castle'");
if ($typ == 'clanky') {
// nacitanie clankov
while ($node_data = db_fetch_object($res_story)) {
if (!empty($node_data->latitude) && !empty($node_data->longitude)) {
$clanky[] = (
$node_data->latitude .','. $node_data->longitude
.':'
.'<h1>'
.l($node_data->title, 'node/'.$node_data->nid)
.'</h1>'
. theme_location_latitude_dms($node_data->latitude) .', '. theme_location_longitude_dms($node_data->longitude));
}
}
}
if ($typ == 'zamky') {
// nacitanie zamkov
while ($node_data = db_fetch_object($res_castle)) {
if (!empty($node_data->latitude) && !empty($node_data->longitude)) {
$zamky[] = (
$node_data->latitude .','. $node_data->longitude
.':'
.'<h1>'
.l($node_data->title, 'node/'.$node_data->nid)
.'</h1>'
. theme_location_latitude_dms($node_data->latitude) .', '. theme_location_longitude_dms($node_data->longitude)
.(!empty($node_data->field_castle_foto_fid) ? '<p align="center">'. l('<img src="'. base_path() . 'sites/infovylety.cz/files/imagecache/240x150/img/castle/'. $node_data->filename . '">', 'node/'.$node_data->nid, array(html => TRUE)). '</p>' : ''));
}
}
}
// udaje prave zobrazeneho nodu
$nidnow = arg(1);
$qnow = db_query("SELECT l.latitude, l.longitude FROM {location} AS l LEFT JOIN {location_instance} AS li ON l.lid=li.lid WHERE li.nid='%d'", $nidnow);
$loadnow = db_fetch_array($qnow);
$latnow = $loadnow['latitude'];
$longnow = $loadnow['longitude'];
// zavola javacript na zbalitelny fieldset / pravdepodobne zrusit
//drupal_add_js($data = 'misc/collapse.js', $type = 'core', $scope = 'header', $defer = FALSE, $cache = TRUE);
// definovanie mapy clankov- prave zobrazeny node ma okolo seba okruh o vlekosti 15 km
$gmap_clanky = '[gmap markers=yellow::'. implode(' + ', $clanky) .'| markers=white::'. $latnow .','. $longnow .'|zoom=10 |center='. $latnow .','. $longnow .' |width=100% |height=350px |align=center |id=iv_clanky_mapa |control=Large |type=Map| circle='. $latnow .','. $longnow .' + 15]';
// definovanie mapy zamkov - prave zobrazeny node ma okolo seba okruh o vlekosti 15 km
$gmap_zamky = '[gmap markers=yellow::'. implode(' + ', $zamky) .'| markers=white::'. $latnow .','. $longnow .'|zoom=10 |center='. $latnow .','. $longnow .' |width=100% |height=350px |align=center |id=iv_zamky_mapa |control=Large |type=Map| circle='. $latnow .','. $longnow .' + 15]';
// vypisanie mapy
if (($page != '0') && (!empty($latnow)) && (!empty($longnow))) {
if ($typ == 'zamky') {
return theme('gmap', array('#settings' => gmap_parse_macro($gmap_zamky)));
}
if ($typ == 'clanky') {
return theme('gmap', array('#settings' => gmap_parse_macro($gmap_clanky)));
}
}
}
function ivbloky_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$blok[0] = array('info' => 'GMap Clanky', 'cache' => BLOCK_NO_CACHE);
$blok[1] = array('info' => 'GMap Zamky', 'cache' => BLOCK_NO_CACHE);
return $blok;
}
if ($op == 'view') {
switch($delta) {
case 0:
$blok = array('subject' => t('Další články na mapě'), 'content' => iv_bloky_obsah('clanky'));
break;
case 1:
$blok = array('subject' => t('Další zámky na mapě'), 'content' => iv_bloky_obsah('zamky'));
break;
}
return $blok;
}
}
?>
"raw" code :)
#3
Ok, I can reproduce this bug. I used the gmap module where I put a map into a node, and displayed that node in two tabs..
The problem is that the bounding box for the goggle map is wrongly calculated for the second tabpage. The google map displayed on any page is a collection of small images. Only images which intersects with the bounding box should be displayed on the page.
On the attached picture the quicktab with red border should be the bounding box. The problem is that the gmap uses something different. With firebug I highlighted one gmap image (a box with light blue background), this image should not be there as it is outside the bounding box.
So the problem is with position. We need this box to be the same as the tabpage, but I don't know what is causing this. Could be a simple css issue, or a position bug in gmap javascript..
Interesting note: If I launch firebug when the second tabpage is open then that map starts to work correctly and the problem flips to the first tabpage.
#4
#5
Any solution to this problem yet? Im having the same issue with gmaps and tabs. Maps which load properly if accessed via their node url, do not fully load when accessed as part of a quicktabs block. If I launch firebug the map loads as expected. I can then click various tabs on the page and when I return to the map it is loaded ok but if I leave the quicktab page completely, when I return the map does not load properly again.
#6
I am also having an issue with this. Any progress toward getting this resolved would be appreciated.
#7
same problem here using quicktabs 6.x-2.0-rc3
#8
Note that the title of this issue is a little mis-leading. I don't believe that the issue is with 2 gmaps, it's actually any gmap which is not displayed on the first tab.
If I display a gmap on the first tab then it works fine. On any other tab then it's broken.
I think this may be something to do with the gmap being initialized when it's container is hidden.
I saw a fix for a similar issue, in a different context, was to have the container positioned off screen rather than actually hiding it. I don't know if a similar technique would be possible here or whether it would work.
Matt
#9
from http://docs.jquery.com/UI/Tabs
there are 2 solutions described on that page..
#10
Following on from Pasqualle's response above I have looked into this a little further. The two solutions suggested are:
I looked at using resizeMap() and I think that in some cases that might solve the problem of corruption, but it didn't solve one of my problems which was the incorrect centering of the map.
The technique given for hiding non-active tabs by rendering them off-screen does seem to work, though I wasn't able to make it work just by using CSS. Instead I have made a patch which changes quicktabs to use this technique and attaching the patch to this post. The patch has been made against the latest dev release version 6.x-2.x-dev as of 2009-06-16 and can be applied from the quicktabs module folder by: patch -p0 < /path/quicktabs-352247-10.patch
The patch fixes both problems that I've seen with this - corruption in the map and incorrect centering of the map, both of which occur when a map is placed on a tab other than the first tab. The patch works by removing the original behavior of using hide() and show() on the tabs to hide/show them. Instead, when javascript is enabled then tabs to be hidden have a CSS class 'quicktabs-hide' added to them and when active that class is removed. Some CSS code is added for that class which positions the element in question off-screen.
I've tested that the fix works on both IE and Firefox and that tabs continue to work when javascript is disabled.
I think this change still needs quite a bit of testing though as this is quite a fundamental change to the way things work so I'm a bit worried it may not work with some browser or conditions.
Hope it helps and please get in touch with me if more info on the patch is required.
#11
During some further testing of the above patch I noticed that, in some cases (maybe all), there was an extra margin added at the bottom of the page. I've made a change to the CSS that was added so that the positioning is set off-screen both to the left and above the page which seems to fix it. This patch replaces the one above, you only need to apply this patch on it's own to the dev release.
#12
I do not believe that the module should change the hiding method. But you can change it now (without hacking the module) with simply adding the following css selector to your theme's css file:
.quicktabs-hide {position: absolute;
left: -10000px;
top: -10000px;
}
http://drupal.org/cvs?commit=239028
this needs documentation..
#13
I'm using the dev version and trying to load a gmap to a tab via ajax. Not too surprisingly it's not working, saying "javascript is required to view this map".
I'm falling back to load all at once for now, but if you can think of a nice fix, it'd be welcome when you get a moment.
Lovely work so far -- I was told about qt yesterday and it's making things a LOT better already. Thank you!
#14
@eddowding: #345175: what could be inside ajax quicktabs
#15
With QuickTabs 6.x-2.x-dev (2009-Jul-18) I still have the problem.
I have only one GMap but it works correctly only if it is in first tab.
Does this release should fixe this issue ?
#16
@srobert72: did you make the changes described in comment #12?
#17
Yes I use default theme Garland.
I wrote CSS fix at the end of
/drupal/themes/garland/style.css.I flushed all caches.
With FireBug in FireFox I can see CSS fix is in use :
HTML :
<div id="quicktabs_tabpage_4_1" class="quicktabs_tabpage quicktabs-hide"><div class="view view--content-map view-id-_content_map view-display-id-default view-dom-id-2">
<div class="view-content">
<div style="width: 100%; height: 500px;" id="gmap-cont_map-gmap0" class="gmap-control gmap-gmap gmap gmap-map gmap-cont_map-gmap">
Javascript is required to view this map.
</div>
<script type="text/javascript">
/* <![CDATA[ */
jQuery.extend(true, Drupal, { settings: { "gmap": ..... } });
/* ]]> */
</script>
</div>
</div>
</div>
CSS :
.quicktabs-hide {left:-10000px;
position:absolute;
top:-10000px;
}
#18
Subscribing
#19
I am also having an issue with this by 6.x-2.0-rc3.
And I found an solution :
(quicktabs.css)
Change from
div.quicktabs_tabpage.nojs-hide {
display: none;
}
To
div.quicktabs_tabpage.nojs-hide {
display: block;
}
and now looks ok.
I'm not sure is this change will cause any other issue.
Just for refer.
#20
@Mree: I am sure that change will cause other issues. For example try to disable javascript in your browser..
#21
#41 and #47 here - http://drupal.org/node/315236 - should be helpful to anyone looking to fix the Gmap Ajax bug