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

CommentFileSizeAuthor
#48 quicktabs_gmap_fix.zip4.07 KBnkschaefer
#47 quicktabs_gmap_fix.zip3.27 KBnkschaefer
#11 quicktabs-352247-11.patch1.08 KBmarshmn
#10 quicktabs-352247-10.patch1.06 KBmarshmn
#3 gmap&qtabs.png49.83 KBPasqualle
ScreenShot002.png242.22 KBAnonymous (not verified)
ScreenShot002.png242.22 KBAnonymous (not verified)
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Pasqualle’s picture

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.

Anonymous’s picture

<?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 :)

Pasqualle’s picture

Version: 6.x-2.0-rc1 » 6.x-2.x-dev
FileSize
49.83 KB

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.

Pasqualle’s picture

Title: Can't display two gmaps proprely » Can't display two gmaps properly
Heather51’s picture

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.

atelier’s picture

I am also having an issue with this. Any progress toward getting this resolved would be appreciated.

esplinter’s picture

same problem here using quicktabs 6.x-2.0-rc3

marshmn’s picture

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

Pasqualle’s picture

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

Why does my slider, Google Map, sIFR etc. not work when placed in a hidden (inactive) tab?

Any component that requires some dimensional computation for its initialization won't work in a hidden tab, because the tab panel itself is hidden via display: none so that any elements inside won't report their actual width and height (0 in most browsers).

there are 2 solutions described on that page..

marshmn’s picture

Status: Active » Needs review
FileSize
1.06 KB

Following on from Pasqualle's response above I have looked into this a little further. The two solutions suggested are:

  • Use resizeMap() to get google maps to refresh it's dimensions etc
  • Use a different technique to hide the non-active tabs

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.

marshmn’s picture

FileSize
1.08 KB

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.

Pasqualle’s picture

Title: Can't display two gmaps properly » How to display two gmaps properly
Component: Miscellaneous » Documentation
Category: bug » task
Status: Needs review » Active

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..

eddowding’s picture

Component: Documentation » User interface
Category: task » bug

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!

Pasqualle’s picture

Component: User interface » Documentation
Category: bug » task
srobert72’s picture

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 ?

Pasqualle’s picture

@srobert72: did you make the changes described in comment #12?

srobert72’s picture

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;
}
farald’s picture

Subscribing

Mree’s picture

Version: 6.x-2.x-dev » 6.x-2.0-rc3

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.

Pasqualle’s picture

@Mree: I am sure that change will cause other issues. For example try to disable javascript in your browser..

kvvnn’s picture

#41 and #47 here - http://drupal.org/node/315236 - should be helpful to anyone looking to fix the Gmap Ajax bug

held69’s picture

I am Having an issue with this as well, using the module conditional fields combined with location.
http://drupal.org/node/730084

The javascript solution could be working for me as well, however i dont know how to implement this in to conditional fields.

some help much appreciated.

Thanks

Pasqualle’s picture

Version: 6.x-2.0-rc3 » 6.x-2.0-rc4

@Mree: nojs-hide was removed in rc4. the correct solution for rc4 is in comment #12

@held69: if I understand correctly you are using the conditional fields module to display a gmap. So you need to find the place where the module hides and shows a field. search for: hide() and show() in the js files. Then replace it with addClass('something-hide') and removeClass('something-hide'), and create the corresponding css. You should check the commit linked in comment #12 to see what was changed in QT.

held69’s picture

@pascalle,

thanks for your reply.

In this file i have tried some adjustments but got syntax errors as a result.

/* $Id$ */

if (!Drupal.ConditionalFields) {
  Drupal.ConditionalFields = {};
}

Drupal.ConditionalFields.switchField = function(id, values, onPageReady) {
  /* For each controlling field: find the controlled fields */
  $.each(Drupal.settings.ConditionalFields.controlling_fields, function(controllingField, controlledFields) {
    if (controllingField == id) {
      /* Find the settings of the controlled field */
      $.each(controlledFields, function(i, fieldSettings) {
        var hideField = true;
        /* Find the trigger values of the controlled field (for this controlling field) */
        $.each(fieldSettings.trigger_values, function(ii, val) {
          if (jQuery.inArray(val, values) != -1) {
            Drupal.ConditionalFields.doAnimation(fieldSettings, 'show', onPageReady);
            hideField = false;
            /* Stop searching in this field */
            return false;
          }
        });
        if (hideField) {
          Drupal.ConditionalFields.doAnimation(fieldSettings, 'hide', onPageReady);
        }
        /* To do: Feature: Multiple controlling fields on the same field, are
           not supported for now. Test: other controlling fields types and widgets. */
      });
    }
  });
}

Drupal.ConditionalFields.doAnimation = function(fieldSettings, showOrHide, onPageReady) {
  /* Multiple fields are enclosed in a wrapper */
  if ($(fieldSettings.field_id).parents('#' + fieldSettings.field_id.substring(13) + '-add-more-wrapper').length == 1) {
    var toSwitch = $('#' + fieldSettings.field_id.substring(13) + '-add-more-wrapper');
  } else {
    var toSwitch = $(fieldSettings.field_id);
  }

  if (Drupal.settings.ConditionalFields.ui_settings == 'disable') {
    var disabled = '';
    if (showOrHide == 'hide') {
      disabled = 'disabled';
    }
    toSwitch.find('textarea, input, select').attr('disabled', disabled);
  }
  /* Avoid flickering */
  else if (onPageReady == true) {
    /* Setting css instead of simply hiding to avoid interference from collapse.js */
    showOrHide == 'show' ? toSwitch.show() : toSwitch.css('display', 'none');
  }
  else {
    switch (Drupal.settings.ConditionalFields.ui_settings.animation) {
      case 0:
        showOrHide == 'show' ? toSwitch.show() : toSwitch.hide();
      case 1:
        /* Don't double top and bottom margins while sliding. */
        var firstChild = toSwitch.children(':first-child');
        var marginTop = firstChild.css('margin-top');
        var marginBottom = firstChild.css('margin-bottom');
        firstChild.css('margin-top', '0').css('margin-bottom', '0');
        if (showOrHide == 'show') {
          toSwitch.slideDown(Drupal.settings.ConditionalFields.ui_settings.anim_speed, function() {
            firstChild.css('margin-top', marginTop).css('margin-bottom', marginBottom);
          });
        }
        else {
          toSwitch.slideUp(Drupal.settings.ConditionalFields.ui_settings.anim_speed, function() {
            firstChild.css('margin-top', marginTop).css('margin-bottom', marginBottom);
          });
        }
      case 2:
        showOrHide == 'show' ? toSwitch.fadeIn(Drupal.settings.ConditionalFields.ui_settings.anim_speed) :
                               toSwitch.fadeOut(Drupal.settings.ConditionalFields.ui_settings.anim_speed);
    }
  }
}

Drupal.ConditionalFields.findValues = function(field) {
  var values = [];
  field.find('option:selected, input:checked').each( function() {
    if ($(this)[0].selected || $(this)[0].checked) {
      values[values.length] = this.value;
    }
  });
  return values;
}       

Drupal.ConditionalFields.fieldChange = function() {
  var values = Drupal.ConditionalFields.findValues($(this));
  var id = '#' + $(this).attr('id');
  Drupal.ConditionalFields.switchField(id, values, false);
}

Drupal.behaviors.ConditionalFields = function (context) {
  $('.conditional-field.controlling-field:not(.conditional-field-processed)').addClass('conditional-field-processed').each(function () {
    /* Set default state */
    Drupal.ConditionalFields.switchField('#' + $(this).attr('id'), Drupal.ConditionalFields.findValues($(this)), true);
    /* Add events. Apparently, Explorer doesn't catch the change event? */
    $.browser.msie == true ? $(this).click(Drupal.ConditionalFields.fieldChange) : $(this).change(Drupal.ConditionalFields.fieldChange);
  });
};

Is it possible for you to specify the point where the .addClass(field-hide) and the .removeClass(field-hide)mentioned under twelve should be placed?

thanks

Pasqualle’s picture

@held69: please add your comment to the Conditional Fields issue, and try to create a patch (or code suggestions), which can be reviewed with the module maintainer and others. I would like to fix QT issues here..

my last comment on this here is: you need to change all lines starting with showOrHide == 'show', and you will probably lose the fade in/out effect option..

held69’s picture

Sorry,

i'll continue my thread here:

http://drupal.org/node/730084

Thanks

EvanDonovan’s picture

The .quicktabs-hide code given in #12 did not work, since the tab was still display: none; I believe. I had to use:

.quicktabs-hide {
  display: block;
  position: absolute;
  left: -10000px;
  top: -10000px;
}

That worked.

EvanDonovan’s picture

What should be done so this "task" can be wrapped up? Where should the documentation go? Can it be submitted as a patch, or is it just for the Drupal handbook?

Should my CSS be tested further first? And, if so, should the status on this be set to "needs review"?

EvanDonovan’s picture

Title: How to display two gmaps properly » Gmap centering has error on hidden Quicktab tabs (was: How to display two gmaps properly)
Pasqualle’s picture

yes, please create a d.o handbook page if you have the time for it

and any help is welcome on other documentation issues also
http://drupal.org/project/issues/quicktabs?component=Documentation

also if someone creates an Advanced help module style help for these kind of issues, then it might be added to the module..

soncco’s picture

Issue tags: +gmap, +tabs, +centering problem

I've used the code on http://drupal.org/node/131034#comment-532642, but my problem persist. To fix it I've changed code:

var flag = true; // Method control
Drupal.gmap.addHandler('gmap',function(elem) {
	var obj = this;
	obj.bind('checkresize',function() {
		obj.map.checkResize();
		if(flag) {
			obj.map.panDirection(+1.6, +2); // Move the map to center
			flag = false;
		}
	});
});

And I've used with :

// This code when tab is showed. I've used my custom tabs
if (Drupal.gmap) {
	Drupal.gmap.globalChange('checkresize', -5)
};

It works for me, but maybe I need suggestions :)

Abeaudrian’s picture

subscribing... have same challenge.

...
Adrian

nirad’s picture

I can confirm that #27 worked for me.

nkschaefer’s picture

I had the same problem, and moving the hidden div didn't seem to work for me either. I just spent a little time reading about the Google Maps API and everything, and I thought I'd share what I did in case it helps anyone else:

1) I'm actually using my own module to control the tabs, but it works almost exactly like Quicktabs (but I can make tabs for individual divs, rather than views, nodes, blocks, etc.). For that reason, I added a line to the JS to fire a custom event, "tabs-hide," when divs are hidden, and "tabs-show" when divs are un-hidden.

2) My GMap is part of a Views attachment. I have a custom helper module to alter the display of the view it's in; I wrote a hook_views_pre_render to add my own Javascript file before the View containing the GMap is shown. This Javascript contains an event listener for my custom "tabs-show" event.

3) Here's where I was confused: I couldn't find a function called "resizeMap" and someone said the map wasn't re-centering when using this function after un-hiding a GMap container. Instead, you need to:
Obtain the gmap by calling Drupal.gmap.getMap(yourmapID) (I think a frequently auto-assigned ID is 'auto1map').
Get a reference to the actual Google Maps object (lower-level than the GMap object) via the gmap object's map attribute.
Call map.checkResize() to fix its dimensions
Fix the latitude and longitude:
Get the latitude and longitude from the gmap object via [object].vars.latitude and [object].vars.longitude
create a GLatLng object with these numbers: new GLatLng(latitude, longitude, false)
Tell the Google Map object (not GMap object) about the coordinates: map.setCenter([GLatLng object you just created])

I realize my post isn't directly Quicktabs-related, but there was so much conversation about this issue here that I thought this would be the best place to post info. Maybe this can help save people time and prevent future questions on this topic.

The one implication this does have for Quicktabs is that maybe custom JQuery events should be fired whenever tabs are clicked to show or hide elements?

ccheu’s picture

#27 didn't work for me. Has anyone tried #31? Any feedback is much appreciated! Cheers!

Aron Novak’s picture

#31 is a good direction, but not perfect. I don't get it why using a fixed value.
I use this in gmaps.js (+Drupal.gmap.globalChange call in quicktabs.js + CSS fix from #27)

// For quicktabs-compatibility
Drupal.gmap.addHandler('gmap',function(elem) {
  var obj = this;
  obj.bind('checkresize',function() {
    obj.map.checkResize();
    obj.map.setCenter(new GLatLng(obj.vars.latitude,obj.vars.longitude), obj.vars.zoom);
  });
});

There is one drawback, it centers the map every time when the user changes between the tabs.

Danny Englander’s picture

I am having the same issue, interested in this.

Note: #36 + #27 worked for me and switching tabs and then back to the tab with the map did not recenter the map if I had navigated with the map beforehand.

Tafa’s picture

#27 worked for me too.
Thanks
T

Danny Englander’s picture

I just discovered that IE 8 renders a nasty error message for the code in #36 (script debugging turned on).

The error I am getting is: 'Drupal.gmap' is null or not an object

I am not really good with Javascript so not sure how to further debug or solve this.

incaic’s picture

#27 worked for me, thanks!

EvanDonovan’s picture

Version: 6.x-2.0-rc4 » 6.x-2.x-dev
Status: Active » Fixed

I added the CSS & JS solutions to a handbook page: http://drupal.org/node/1115726. I'll mark this fixed, then.

Danny Englander’s picture

Status: Fixed » Needs work

I don't believe this is fixed as I mentioned in comment #39 above, I am getting a nasty javascript error in IE 7, 8 & 9 so setting back to needs work.

Note that I have javascript debugging turned on. If you need more info, let me know but you should be able to reproduce it with that setting In any version of IE.

EvanDonovan’s picture

Status: Needs work » Postponed (maintainer needs more info)

@highrockmedia: That is almost certainly a GMap issue (or an issue with JS in another module, besides GMap or Quick Tabs). Can you try following the debugging steps at http://drupal.org/node/1071244?

Also note that the code at #36 is really a last resort if you need it. Try the CSS method that I describe in the handbook page first.

I will mark this fixed again if no reports back in a week.

lennyaspen’s picture

I made the above necessary changes in respective places
but none seems to be working,

Please don`t close the topic yet.

Regards

GiorgosK’s picture

put #27 in your own .css
fixes issue with gmap in hidden tab
and other issues http://drupal.org/project/galleryformatter thumbnails not appearing correctly

nkschaefer’s picture

My last post was kind of obtuse -- but now I've hit a case where I have a Quicktabs block that contains other nested Quicktabs blocks, one of which contains three different maps (one per tab). This caused some problems, and the other suggested solutions didn't work. I built on my previous solution (above) and wrote some code that should be easy for anyone to dump into a custom module and solve the problem, without hacking anything.

  • Step 1
    Since you know better than anyone else what page/path your Quicktabs block will show on, you need to write a custom module that can add a custom Javascript file on the correct page. Or, if you want to take the easy way out, you can just write a hook_init() and add the Javascript file to every page.

    Important: this Javascript file needs to be added AFTER the Quicktabs Javascript file, because its behavior must be bound after the Quicktabs behavior. In Drupal 7 this can be easily achieved by setting the "weight" parameter in drupal_add_js() -- something like this:

    drupal_add_js(drupal_get_path('module', 'mymodule') . '/quicktabs_gmap_fix.js', array('weight' => 99));
    
  • Step 2
    Use this Javascript file. You don't need the CSS trick above or anything - it'll fix up the right map whenever it's un-hidden via Quicktabs. And this works for my special case where I have a bunch of maps in nested Quicktabs blocks. This code is written for Drupal 7, but I'll also attach a version that's compatible with Drupal 6 (the changes are really small).
    /**
     * quicktabs_gmap_fix.js
     *
     * This provides some Javascript code to fix problems that exist with displaying Google Maps
     * from the GMap module within a Quicktabs block. Normally, when tabs are clicked and content
     * is hidden/shown, the map needs to refresh itself but is not told to do so. This file simply
     * forces each map to refresh when the user unhides it.
     */
    
    Drupal.quicktabs_gmap_fix = {};
    
    Drupal.quicktabs_gmap_fix.fixMap = function(event){
    	
    	var qtBlock = $(event.target).parents('.block-quicktabs');
    	var activeDiv = qtBlock.find('div.quicktabs_main').children('div.quicktabs-tabpage:not(.quicktabs-hide)');
    	
    	// Since Quicktabs blocks can contain other Quicktabs blocks, here we need to examine each
    	// GMap div that is a child of the currently-active quicktab "page" div. Since that div can
    	// contain other Quicktabs blocks, it may contain other GMap divs that are currently still
    	// hidden. Therefore, we'll check each GMap div and make sure ALL of its Quicktabs wrapper
    	// divs are currently visible. If so, the map has just been un-hidden and we need to re-center
    	// it.
    	activeDiv.find('div.gmap-gmap').each(function(index, object){
    		var visible = true;
    		$(this).parents('div.quicktabs-tabpage').each(function(){
    			if ($(this).hasClass('quicktabs-hide')){
    				visible = false;
    			}
    		});
    		if (visible){
    			var gmap = $(this);
    			// GMap map IDs are accessible through the CSS ID of the wrapper divs.
    			var id = gmap.attr('id');
    			var idArr = id.split('-');
    			var mapId = idArr[1];
    			var mapObj = Drupal.gmap.getMap(mapId);
    			// Re-center the map.
    			mapObj.map.checkResize();
    			mapObj.map.setCenter(new GLatLng(mapObj.vars.latitude, mapObj.vars.longitude, false) , mapObj.vars.zoom);
    		}
    	});
    }
    
    Drupal.behaviors.quicktabs_gmap_fix = {};
    Drupal.behaviors.quicktabs_gmap_fix.attach = function(context, settings){
    	// Bind map-fixing behavior to the "click" event. Note that this must be bound after the
    	// Quicktabs behavior, so this JS file must be added later than the Quicktabs sheet.
    	$('ul.quicktabs-tabs').children('li').each(function(index, object){
    		$(this).children('a').bind('click', Drupal.quicktabs_gmap_fix.fixMap);
    	});
    }
    
    })(jQuery);
    
nkschaefer’s picture

FileSize
3.27 KB

Here's a Drupal 7 module that does everything above automatically (but not totally optimal performance-wise because it adds its Javascript to every page).

nkschaefer’s picture

FileSize
4.07 KB

And here's a Drupal 6 version of that same module. Hopefully this will help someone.

nadavoid’s picture

subscribing.

lennyaspen’s picture

@nkschaefer
I applied your module
and the quicktab fix javascript loads after the quicktabs javascript itself
but the problem still persist

the only way to make it work is to make the gmap tab open as default

Exciliknite’s picture

Same problem with google charts api.
This is really annoying.

leahmd’s picture

subscribing

eta:
I had just given up (again) for now after trying the css and gmap.js additions, it still wasn't working properly. I then went back and edited my location block gmap macro widths to finite px, width=400px | height=400px, instead of width=100%. It suddenly all worked on the refresh. Phew, I'll count myself lucky. Thanks all who contributed.

oceanos’s picture

@purplepaisley68 - you just saved my life, just in time! I wondered why #27 didn't work for me - now it does!

@all others - thank you for this very helpful thread.

Marko B’s picture

@nkschaefer why are you doing this only for quicktabs? I have the same problem with basic collapsing, this fix should be broadened if possible.

http://drupal.org/node/1352802#comment-5290440

Frederic wbase’s picture

for me the problem still exists for version 6.3.0 even after enabling the custom module and setting a fixed width & height in the gmap macro :(...

Any tips?

Marko B’s picture

Frederic wbase’s picture

@deepM

Your sollution didn't work for me, but i have fixed it by adding some javascript in the quicktabs.js on line 155

 // Show the active tabpage.
  if (tab.tabpage.hasClass('quicktabs_tabpage')) {
    tab.tabpage.fadeIn('slow').removeClass('quicktabs-hide');
    // GMap map IDs are accessible through the CSS ID of the wrapper divs.
    	var gmap = tab.tabpage.find('div.gmap-gmap');
			var id = gmap.attr('id');
			var idArr = id.split('-');
			var mapId = idArr[1];
			var mapObj = Drupal.gmap.getMap(mapId);
		// Re-center the map.
			mapObj.map.checkResize();
			mapObj.map.setCenter(new GLatLng(mapObj.vars.latitude, mapObj.vars.longitude, false) , mapObj.vars.zoom);
  }

This sollution is based on http://drupal.org/node/352247#comment-4672750, just that i diden't used the module but only the js for recentering.

grts

fre

Frederic wbase’s picture

In combination with carouFredsel you can fix it like this:

       /**
	 * Caroufredsel implementation for our locations
	 */
	 
	if($("ul.locations").length){
		$('a',$('li:first','ul.location-navigation')).addClass('active');	
		$("ul.locations").carouFredSel({
			items: 1,
			scroll: {
				fx: "fade",
				onAfter: function(oldItems, newItems, newSizes){
					// Show the active tabpage.
  				if (tab.tabpage.hasClass('quicktabs_tabpage')) {
  				  tab.tabpage.fadeIn('slow').removeClass('quicktabs-hide');
  				  // GMap map IDs are accessible through the CSS ID of the wrapper divs.
  				  var gmap = tab.tabpage.find('div.gmap-gmap');
						var id = gmap.attr('id');
						var idArr = id.split('-');
						var mapId = idArr[1];
						var mapObj = Drupal.gmap.getMap(mapId);
						// Re-center the map.
						mapObj.map.checkResize();
						mapObj.map.setCenter(new GLatLng(mapObj.vars.latitude, mapObj.vars.longitude, false) , mapObj.vars.zoom);
  				}	
				}
			},
			auto: false
		});	
	},
Scott M. Sanders’s picture

#57 works great, albeit a little slow, but now it's centered.

Just in Quick Tabs 7.x-3.4, insert it in quicktabs.js at line 49.
And change "quicktabs_tabpage" to "quicktabs-tabpage".

Scott M. Sanders’s picture

#57 was giving me JS errors and somehow reloading the whole page on tab change -- because I do not actually use the legacy GMap module, just the iframe code from Google Maps.

But #27 works beautifully, fast with no reloading, and it solves not just Google Maps centering but anything that may render funny if hidden.

It should be added to Quick Tabs.

jienckebd’s picture

#27 worked great, thanks!!

ice70’s picture

@purplepaisley68 - thank you for the heads up on this one, it was driving me nuts seeing all the other users reporting success when I was getting a broken map :(

But, does any one have a solution to the 100% width map? I am using the Omega layout and there are several sizes this map could be depening on the screen size and 100% would be ideal!

Thank you for any pointers
ice70

oneidprod’s picture

For anyone who might be trying to get this to work with the accordian tab style and building off of #27 using 7.x-3.4 this worked for me.

.ui-accordion-content {
display: block !important;
position: absolute !important;
left: -10000px;
}

.ui-accordion-content-active {
left: 0px !important;
position: relative !important;
}

If you don't want to apply to every accordian block then you can use this

#block-quicktabs-yourblockname .ui-accordion-content {
display: block !important;
position: absolute;
left: -10000px;
}

#block-quicktabs-yourblockname .ui-accordion-content-active {
left: 0px !important;
position: relative;
}

Make sure you use the !important element or this won't work. Also, the !important element won't work in IE6. I started with the 2nd example that's why there's extra !important elements in the 1st example as they were needed when applied for every accordian block.

jordiserra’s picture

#27 works, but in my case I have 4 tabs, and this affected all other tabs. I applied this CSS only to the gmap tab, using the tab ID.

Thanks for this thread!

steven_kropp’s picture

I second that!

I had exactly the same issue, and thought I was going crazy over here... and yes I am too using Omega, and am wondering if I can't use 100% width... how am I going to execute this on my tablet and mobile versions.

Did you find any solutions?

brandy.brown’s picture

#47 used in conjunction with #12 worked for me. Thank you!!!!

LWB’s picture

#27 worked great except it doesn't work again when making the gmap width 100% (as stated in 65). Any solution for this?

brandy.brown’s picture

Did you try using #47 with #12? I used that combo and am able to display maps at 100%.

miccelito’s picture

Stated in the thread the Google Map Centering issue fix for css is

.quicktabs-hide {
	display:block;
	position:absolute;
	left:-10000px;
	top:-10000px;
}

But this seems to work only when qtabs IS NOT Ajax.
Any additional css for showing Google Map when qtabs IS Ajax?

modiphier’s picture

perfect.. thanks! #69 worked perfectly for me. I have a default tab with a content node and then I have 9 additional tabs each with a separate embedded gmap nodes. This css corrected all of them loading to the correct view instead of all my markers out of view.

thanks

Marfio’s picture

Issue summary: View changes

#27 worked.

I was with the same truble as #70

Thank you

vijeesh@fingent’s picture

This code worked for me:-

.quicktabs_main {
    position: relative;
}
.quicktabs-tabpage {
    display: block;
    visibility: visible;
    width: 100%;
}
.quicktabs-tabpage.quicktabs-hide {
    display: block;
    visibility: hidden;
    top: 0px;
    left: 0px;
    position: absolute;
    z-index: -1;
}
diegops’s picture

#72 worked for me...

Shiraz Dindar’s picture

#72 worked for me as well (my issue being the google map was only partially rendered, ie. lots of grey area for google maps inside a quicktab when not in the first tab. In my case the map is a geofield google map display and the tabs are created programmatically as node tabs)

Thank you @vijeesh and all!

junkbox’s picture

+10,000
Thanks Vijeesh! (#72)

travis09’s picture

#72 worked for me for a QuickTabs and multiple Fullcalendar views. Thanks Vijeesh.

Malek75’s picture

#72 worked for me. Thanks!

wasimhyder09’s picture

Comment # 27 worked for me.

Thanx @EvanDonovan.
You saved my day :)

joro78’s picture

#72 Worked, thanks Vijeesh.

stpaultim’s picture

I had opened a similar issue #2915606: Maps don't render if they are not the default tab - The CSS provided in #72 solved my problem. Thanks!

Nick Hope’s picture

#72 worked for me with Quick Tabs 8.x-3.0-alpha2 and Geolocation Field 8.x-2.0-beta1. Thanks vijeesh!

apaderno’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)

I am closing this issue, since it's for a Drupal version no longer supported.