Streaming live at 10am (PST)

Google Maps JavaScript API - CMS map with multiple locations

Hello All,

I am making website for real estate developer and we need to create a map that will show location of all of the projects. I managed to figure it out by using JS, Collection Lists and HTML embed. From now on I will assume that you know everything about aforementioned features, and not going to go deep into explaining how to use them.

I am in no way an expert in JavaScript and cannot guarantee that it will work in your projects as it did for me. If you have a way to improve upon my tutorial, please feel free to write below.

I was using this demo - https://wrightshq.com/playground/placing-multiple-markers-on-a-google-map-using-api-3/ as a basis for my implementation. Feel free to check it out and reverse engineer it as I did.

Step 1. Get your API key

It is not absolutely necessary to obtain it before you start designing your website, but you must have it once your website goes live. You can get it here - https://cloud.google.com/maps-platform/

Step 2. Create your collection

In my case, I created collection “Projects” where among others I have a text field “Google Maps Coordinates”. In this field I input coordinates for every project in standard GM format (e.g. -88.052509, 172.048887)

Step 3. Create a page

Create a page where you want your map to be displayed on. In my case I’ve created a static page onto which I will drop a Collection list linked to “Projects”.

Step 4. Add JS code before </body> tag

<script>

jQuery(function($) {

    var script = document.createElement('script');
    script.src = "//maps.googleapis.com/maps/api/js?key=**YOUR-API-KEY**&callback=initialize";
    document.body.appendChild(script);
});

function initialize() {
    var map;
    var bounds = new google.maps.LatLngBounds();
    var mapOptions = {
        mapTypeId: 'roadmap'
    };

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

    var infoWindow = new google.maps.InfoWindow(), marker, i;

    for( i = 0; i < markers.length; i++ ) {
        var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
        bounds.extend(position);
        marker = new google.maps.Marker({
            position: position,
            map: map,
            title: markers[i][0]
        });

        google.maps.event.addListener(marker, 'click', (function(marker, i) {
            return function() {
                infoWindow.setContent(infoWindowContent[i][0]);
                infoWindow.open(map, marker);
            }
        })(marker, i));

        map.fitBounds(bounds);
    }

    var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
        this.setZoom(14);
        google.maps.event.removeListener(boundsListener);
    });

}

</script>

Important thing to keep in mind is that you have to replace **YOUR-API-KEY** with your actual API key from Google. If you just want to mess around without API key, just erase key=**YOUR-API-KEY**& from the string.

Step 5. Create wrappers for your map

Create 2 <div> blocks, one inside another.

Outer <div> has to have id and class called map_wrapper, this block will shape the size of your map. Feel free to add any width and height to this block.

Inner <div> has to have an id map_canvas with width and height being 100%.

Step 6. Create HTML embed for JS arrays

Just underneath a map, drop a HTML embed block with this bit of code:

<script>

var markers=[],infoWindowContent=[];

</script>

It creates two empty JS arrays with marker locations and information blocks that we will fill with information from our collection.

Step 7. Create a Collection list with HTML embed in Collection item

Create a collection list, link it to your Collection. In my case it is collection “Projects”. You can limit amount of Items according to your needs, it is totally up to you. Drop an HTML embed block into collection item .

Step 8. Add code to HTML embeds to fill aforementioned JS arrays

Drop this code into HTML embed:

<script>

var marker_**SLUG** = ['**NAME**', **COORDINATES**]; markers.push(marker_**SLUG**);
var iwc_**SLUG** = ['**YOUR-HTML-HERE**'];
infoWindowContent.push(iwc_**SLUG**);

</script>

Replace in each instance **SLUG** with slug of your collection item, **NAME** with name of your collection item and COORDINATES with GM coordinates. This will fill JS arrays with information about our Collection items.

**YOUR-HTML-HERE** can be replaced with any HTML of your choice. This will reflect a hint on a map when map marker is pressed.

Step 9. Publish your project

And enjoy your work!

5 Likes

Looks great. Do you have the link where we can see your map working?

Just put this project to be cloned: https://webflow.com/website/Google-Maps-with-Multiple-locations-and-CMS?s=map-cms

Hope it helps.

Thanks,

Renan

Hey man,

i’ve been through every “workaround” under the sun for this, and yours seems to be the clearest - unfortunately it’s not working and i don’t know enough JS to troubleshoot myself.

Is there any chance you could share the final site / read-only project so i can reverse engineer?

Renan’s clonable project is great but his technique is too different to yours for me to be able to troubleshoot with.

Thanks in advance,
-James

1 Like

It would be a huge help for everyone. :point_up:

Thanks for this tutorial @psoldunov! It’s been so useful to help show multiple locations from a CMS collection on a single map. Your tutorial is definitely the clearest and easiest to follow and makes the best use of the CMS so that all a user has to do is another item to the Collection List and it automatically shows on the map. No adding extra lines of code etc.

The only thing that got me a bit stuck was using the {{SLUG}} within the variable names in Step 8 e.g. marker_{{SLUG}} as JavaScript doesn’t allow the use of ‘-’ within variable names as it thinks it is a subtract operator.

I tried each of the variables without the dynamic {{SLUG}} field added and it worked! So my code was:

<script>

var marker = ['**NAME**', **COORDINATES**]; markers.push(marker);
var iwc = ['**YOUR-HTML-HERE**'];
infoWindowContent.push(iwc);

</script>

I didn’t think this would work as all the variables would be named the same. But I think because the code is generated dynamically by each individual collection item, they must not be within the same scope and therefore the variable names can be the same.