0

I've got a tabbed SafeCracker form and one of the fields is a Google Maps for ExpressionEngine field. I've noticed an issue where the map only loads properly if it's on the first/selected tab when the page loads. If it's on another tab, then when you click that particular tab, the map doesn't display correctly.

I believe it's an issue to do with the map needing to be redrawn as the tab it's within is clicked, and it sounds like a similar issue this other question. But I can't figure out how to implement or adapt that other solution to fix my problem, though it might be because I'm using a SafeCracker field and different template code so the other solution might not apply completely to my situation.

So I'm posting this as a new question, and any advice on this would be appreciated. My stripped-down template code is below:

{exp:safecracker channel="event" include_jquery="no" datepicker="no" return="/events"}

  <div class="tabbed-form">

    <ul class="tabs">
      <li><a href="#tab1" class="selected">Tab 1</a></li>
      <li><a href="#tab2" class="tab-with-map" data-id="gmap_output_cf_event_map_location">Tab 2</a></li>
      <li><a href="#tab3">Tab 3</a></li>
    </ul>

    <div id="tab1" style="display: block;">
      <h2>Tab 1</h2>
    </div><!--tab1-->

    <div id="tab2" style="display: none;">
      <h2>Tab 2</h2>
      {field:cf_event_map_location}
      <input name="cf_event_map_latitude" type="hidden" value="{cf_event_map_latitude}" />
      <input name="cf_event_map_longitude" type="hidden" value="{cf_event_map_longitude}" />
    </div><!--tab2-->

    <div id="tab3" style="display: none;">
      <h2>Tab 3</h2>
    </div><!--tab3-->

    <input type="submit" value="Save" />

  </div><!--tabbed-form-->

  <script type="text/javascript">
    $('.tabbed-form .tabs').kosTabs();
  </script>

<script type="text/javascript">

$(document).ready(function() {

    // Trigger represents any selector you want to trigger the map to be redrawn

    $('.tab-with-map').click(function() {

        var $t     = $(this);
        var id     = $t.data('id');
        var map    = window[id+'_map']; 
        var center = window[id+'_options'].center;
        var bounds = window[id+'_bounds'];
        var delay  = 500;

        /* Allows the animation to start before the map is redrawn, 
           the 500(ms) can be adjusted for optimal performance. 
           If no animation is present, use 0 or remove the delay 
           entirely. */

        setTimeout(function() {
            google.maps.event.trigger(map, 'resize');

            for(var x = 0;x < markers.length;x++) {
                bounds.extend(markers[x].getPosition());
            }

            // This will center the map on the calculated bounds
            map.fitBounds(bounds);
            map.setZoom(options.zoom);

            /* Do not use setCenter and fitBounds, use only the one that works best for you */

        }, delay);

        return true;
    });

});

</script>


{/exp:safecracker}

Edit: I've updated my code to show how I've tried (unsuccessfully) to use Justin's code from the other answer linked to above.

4
  • Can you confirm that if the browser window is resized with it redraw the form correctly? Feb 14, 2013 at 23:36
  • Hi Justin - I've just checked and yes, if I resize the browser, the map redraws itself (though with a different centre point) and works correctly.
    – Stephen
    Feb 15, 2013 at 0:30
  • 1
    You might want to try this alternate for the whole issue - turned up in Anna_MediaGirl's comment to Justin's December post. In essence, don't try to blank and then redraw the complex Google Map item -- simply push it off the visible page to hide it, then bring it back when the tab should show it. stackoverflow.com/questions/1428178/…, and look at the answer with 12 votes. One nice thing, if it will work for you, is that it would avoid redoing map centering. If doesn't work, more info is in that same post. Feb 22, 2013 at 3:17
  • Thanks. I did look at those suggestions and try them, but couldn't get them working either I'm afraid.
    – Stephen
    Feb 22, 2013 at 15:37

2 Answers 2

1

There is actually a better answer to this question. Here is the updated code:

$(".tabs").tabs({
    show: function() {
        if(Gmap.instances.length > 0) {
            Gmap.instances[0].resize();
        }  
    }
});
0
2

Here is an example of how to fix the issue using jQueryUI Tabs. It could work with any other tab library, you just need to change the callback and the conditional. Basically you just need to get access to the Gmap instance in question and resize the map, and then re-center it. It's really simple.

$(document).ready(function() {
        $('.tabs').tabs({

        show: function(event, ui) {
            if(ui.panel.id == 'map') {
                var instance = Gmap.instances[0];

                google.maps.event.trigger(instance.map, 'resize');
                instance.map.setCenter(instance.center);
            }
        }

    }); 
});
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.