Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Create a Single-page App Using Google Maps that You Can Run Without a Web Server

4.94/5 (5 votes)
7 Nov 2013CPOL3 min read 18.6K  
This is an alternative for How to Create a jQuery UI-powered Web Page that Requires No Hosting

Introduction

This is a refactored version of "How to Create a jQuery UI-powered Web Page that Requires No Hosting", with highlights of what I changed and why. Not all the code is posted here, just the main refactoring of the JavaScript. The complete code is at https://github.com/morganestes/nfl-map

Background

The code originally presented by the author was intended to copy and paste into a new HTML file and run. Doing that threw a number of errors in the browser and left me with a green window, so I set out to debug and rework some of the code. 

What I changed 

Here's the quick overview of what changes I saw that I wanted to address:

  • Opening comment tag throws site out of HTML5 standards and into quirks mode. 
  • The call to include the external script gomap.js throws an error. 
  • CSS syntax error caused by ;; on line 21. 
  • The formatted code in the article has added line breaks in comments that were parsed as JS and broke the loading of code. 
  • Some of the JavaScript code could be reformatted for consistency and to make it easier to read (and maintain). 
  • HTML comment style doesn't work inside JS, so parsing breaks. Switch to JS-style /* comment */ blocks with comments starting on lines 931 & 945. 
  • Holy Cow! ~30 calls to the same function ($.goMap.createMarker()), all in a row. How about a loop, hmmm? 
  • East Rutherford is in New Jersey. 
  • Make the states all abbreviations for consistency. 
  • The h1 tag isn't exactly semantic here, so I'll change it to something else. 

After the initial formatting changes to return the code to a working condition in the browser, I set to work on the calls to createMarker(), which start on line 951 in the original example. I knew I wanted to loop through all these calls, and I needed to store the data in an object.

JavaScript
/* Original call passes an object, so we'll just extract that out. */
$.goMap.createMarker({
address: 'San Francisco, California',
title: 'San Francisco 49ers',
html: '<h1>San Francisco 49ers</h1>'
}); 
JavaScript
/* New object of objects. */ 
var teams = {
      team: {
        address: '',
	title: '',
	html: '<h1>same as title</h1>'
      }
}; 

Each team can be accessed through teams[i], which we'll do inside our loop. We use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">hasOwnProperty</a> to only go through the object items we're including and exclude the inherited properties. 

JavaScript
for (var i in teams) {
        if( teams.hasOwnProperty(i)) {
            var team = teams[i];
            $.goMap.createMarker({
                address: team.address,
                title: team.title,
                html: team.html
            });
        }
    }

Let's look at the teams object again. I noticed that the html property is the same as the title, so we can remove it and add the tag to the object passed to createMarker(). While we're in there, let's make it a bit clearer what data we're actually storing in the teams object.

JavaScript
var teams = {
	team: {
		city: '',
		name: ''
	}
};

for (var i in teams) {
        if( teams.hasOwnProperty(i)) {
            var team = teams[i];
            $.goMap.createMarker({
                address: team.city,
                title: team.name,
                html: "<span class='team-name'>" + team.name + "</span>"
            });
        }
    }

Looking better, but let's make one more change: This loop can be refactored into a function for reuse. Although it's not really needed right now, we should plan for the future as much as possible.

JavaScript
/* Our teams, all nice and neat. */
var teams = {
        atl: {
            city: 'Atlanta, GA',
            name: 'Atlanta Falcons'
        },
        buf: {
            city: 'Buffalo, NY',
            name: 'Buffalo Bills'
        },
        chi: {
            city: 'Chicago, IL',
            name: 'Chicago Bears'
        }
      ...
};
JavaScript
/* Our new function declaration and call. */
var createMapMarkers = function( objMarkers ) {  
	for ( var i in objMarkers ) {
            if( objMarkers.hasOwnProperty(i) ) {
                var team = objMarkers[i];
                console.log( team );

                $.goMap.createMarker({
                    address: team.city,
                    title: team.name,
                    html: "<span class='team-name'>" + team.name + "</span>"
                });
            }
        }
    };

createMapMarkers( teams ); 

Points of Interest

While the loop through the teams object to generate a pin makes the code easier to read and follow, there are still some optimizations that can be done:

  • Caching assets (specifically, map tile images) to make refreshes faster. 
  • Making a single call to the service, storing the results in an object, then parsing that object to display the pins. 

Also, ESPN has a mashup API that can be used to display the team logo, stats, etc. It's what I used to get the order of teams in the teams variable. 

History

Each major code change was documented with Git commits. Follow along at https://github.com/morganestes/nfl-map.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)