Question

I have a very strange issue that I will try my best to explain.

I have a single page backbone application which loads new pages through AJAX.

One of the pages (the contact us page) is a full screen Google map with a contact form laid over the top.

The problem that I am having is that I am having issues with the location that the map loads in when navigating from a specific page.

Here are the pages which work and don't work:

Home         -> Contact Us = Map loads in correct location
Finding True -> Contact Us = Map loads aprox 5km north of correct location
Work         -> Contact Us = Map loads in correct location
People       -> Contact Us = Map loads aprox 2km north of correct location
Social       -> Contact Us = Map loads in correct location

I cannot work out for the life of me why the Finding True and People pages are causing the map to load incorrectly. The same code is run every time.

Here is the view for Contact Us:

app.ContactUsView = Backbone.View.extend({
    el: '#contact_us',
    events: {
        'submit #contact_form': 'submitForm'
    },
    initialize: function() {
        this.$el = $(this.el);
        this.$form = $('#contact_form');

        this.setMetaData('Contact Us | ' + app.site_name, null, null);
        this.setCurrentPageHeight(this.$el);
        app.script_gmaps = (app.script_gmaps ? this.setUpMap() : $.getScript('https://maps.googleapis.com/maps/api/js?sensor=false&key=AIzaSyDU64cYJcx0W2jFuv0Jh439Vgrqta0OKTg&callback=app.contact_us_view.setUpMap', function(){}));

        app.script_jquery_validate = (app.script_jquery_validate ? this.setClientSideValidation() : $.getScript('js/vendor/jquery.validate.min.js', function(){
            app.contact_us_view.setClientSideValidation();
        }));
    },
    setClientSideValidation: function () {
        this.$form.validate();
    },
    submitForm: function(event) {
        event.preventDefault();

        this.$form.find('.return').html('Sending your message...');

        $.ajax({
            dataType: "json",
            type: "POST",
            url: 'send.php',
            data: this.$form.serialize(),
            success: function(data){

                if (data.status == 'error') {

                    app.contact_us_view.showErrorMessage(data);

                } else {

                    app.contact_us_view.messageSent(data);

                }
            }
        });
    },
    showErrorMessage: function (data) {
        this.$form.find('.return').html(data.message).parent().addClass('error');
    },
    messageSent: function (data) {
        this.$form.find('input[type!=submit], textarea').val('');
        this.$form.find('.return').html(data.message).parent().removeClass('error');
    },
    setUpMap: function() {
        if($('#map_canvas').length === 0) return false;

        var mapLatLong = new google.maps.LatLng(51.5174456, -0.1305081);
        var markerLatlng = new google.maps.LatLng(51.5170951, -0.1367416);

        var mapOptions = {
            zoom: 16,
            center: mapLatLong,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }

        var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

        var contentString = '<div id="content">'+
                                '<div id="siteNotice">'+
                                '</div>'+
                                '<h1 id="firstHeading" class="firstHeading">BrocklebankPenn</h1>'+
                                '<div id="bodyContent">'+
                                    '<p>5th floor, 58-60 Berners Street,<br />London,<br />W1T 3NQ,<br />United Kingdom</p>'+
                                    '<p>+44 (0)20 3137 7034</p>'+
                                '</div>'+
                            '</div>';

        var infowindow = new google.maps.InfoWindow({
            content: contentString
        });

        var marker = new google.maps.Marker({
            position: markerLatlng,
            map: map,
            title: 'BrocklebankPenn'
        });

        google.maps.event.addListener(marker, 'click', function() {
            infowindow.open(map,marker);
        });

        infowindow.open(map,marker);

        return true;
    },
    removeView: function() {
        this.$el.parent().remove();
        this.remove();
    }
});

Here is the code for Finding True:

app.FindingTrueView = Backbone.View.extend({
    el: '#finding_true',
    initialize: function(){
        this.$el = $(this.el);
        this.setMetaData('Finding True | ' + app.site_name, null, null);
        $(window).scroll(this.showOverlay);
        this.showOverlay();
    },
    showOverlay: function() {
        var height = $(window).scrollTop() + $(window).height();

        var reveal_offset = $('.section.reveal').offset().top + ($('.section.reveal').height() * 0.7);
        var simplify_offset = $('.section.simplify').offset().top + ($('.section.simplify').height() * 0.7);
        var amplify_offset = $('.section.amplify').offset().top + ($('.section.amplify').height() * 0.7);
        var threesteps_offset = $('.three-steps').offset().top + ($('.three-steps').height() * 2.5);

        if (height >= threesteps_offset) {
            $('.three-steps .fadein').addClass('active');
        }

        if (height >= reveal_offset) {
            $('.section.reveal').addClass('show_overlay');
        }

        if (height >= simplify_offset) {
            $('.section.simplify').addClass('show_overlay');
        }

        if (height >= amplify_offset) {
            $('.section.amplify').addClass('show_overlay');
        }

        if($(window).scrollTop() > (0.25 * $('#current_page article').height())) {
            $('.page-header .scroll-to-content').addClass('inactive');
        } else {
            $('.page-header .scroll-to-content').removeClass('inactive');
        }
    },
    removeView: function() {
        $(window).unbind('scroll');
        this.$el.parent().remove();
        this.remove();
    }
});

Here is the view for People:

app.PeopleView = Backbone.View.extend({
    el: '#people',
    initialize: function(){
        if(!app.script_linkedIn) {
            app.script_linkedIn = $.getScript('//platform.linkedin.com/in.js');
        }
    },
    removeView: function() {
        this.$el.parent().remove();
        this.remove();
    }
});

If anyone can help that would be amazing!

Thanks, Luke.

UPDATE

So I was stepping through the code and making sure that the google.maps object has the same Long and Lat every time.

Unfortunately the Long and Lat is the same every time so I really cannot work out why this is loading in different locations.

Was it helpful?

Solution

So I finally got to the bottom of this issue.

The problem was related to the way I load in a new page. I do this by getting the page via AJAX, insert this into an off screen element and then slide it in like a carousel.

What I hadn't noticed is that the off screen element did not have the correct height, the height was being set to the height of the current active page. This then caused the map to set the long and lat in the center of a map at the incorrect size.

When the off screen page is slid in, the height is then changed to 100% of the browser but the map was not changed to reflect this which meant the long and lat were not displayed correctly.

I now set the height of the off screen page before it has the AJAX content loaded into it and this solves my issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top