Skip to content

Instantly share code, notes, and snippets.

@japboy
Last active May 17, 2017 14:45
Show Gist options
  • Save japboy/efb780beaf7088902d95 to your computer and use it in GitHub Desktop.
Save japboy/efb780beaf7088902d95 to your computer and use it in GitHub Desktop.
Vue.js sample using Google Maps API
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue.js sample using Google Maps API</title>
<style>
.v-transition {
height: auto;
opacity: 1;
transition-duration: 0.2s;
transition-property: height, opacity;
}
.v-enter, .v-leave {
height: 0;
opacity: 0;
}
.suggested {
background-color: #fff;
font-family: sans-serif;
margin: 0;
position: relative;
width: 100%;
}
.suggested > dt {
color: rgb(200,200,200);
font-size: smaller;
padding: 3px;
}
.suggested > dd {
margin: 0;
padding: 3px 6px;
}
.suggested > dd:hover {
background-color: rgb(240,240,240);
color: rgb(100,100,100);
}
#nav {
box-sizing: border-box;
left: 0;
padding: 0.3rem;
position: absolute;
top: 0;
width: 100%;
z-index: 1;
}
#map-canvas {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 0;
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<script src="//maps.googleapis.com/maps/api/js?key=AIzaSyAbz4NWK8NfeybeMGfBqQyablVMv2Xm0Lw"></script>
<script type="x-template" id="tmpl-form">
<input type="text" placeholder="Put anything." autofocus v-model="text" v-bind:style="styleText">
<dl class="suggested" v-if="suggested" v-transition>
<dt>Suggested Countries</dt>
<dd v-for="country in countries">{{country.name.common}} / {{country.name.official}}</dd>
</dl>
</script>
<script defer>
(function (w, d, n, _, $, Vue, GM) {
/** jQuery functions */
var documentLoaded = function () {
var dfr = new $.Deferred();
$(d).ready(dfr.resolve);
dfr.promise();
};
/** Vue ViewModels */
Vue.component('autocomplete-input-box', {
replace: true,
template: '#tmpl-form',
data: function () {
return {
text: '',
styleText: {
boxSizing: 'border-box',
fontSize: '1.2rem',
padding: '3px',
position: 'relative',
width: '100%'
},
countries: []
};
},
computed: {
suggested: function () {
return 0 < this.countries.length && 0 < this.text.length;
}
},
watch: {
text: function (val, old) {
if (val === old || 2 > val.length) return;
this.$dispatch('lookup:dispatch', val);
}
},
events: {
'lookup:broadcast': function (suggestedCountries) {
this.$set('countries', suggestedCountries);
}
}
});
var nav = new Vue({
data: {
countries: []
},
events: {
'lookup:dispatch': function (text) {
var countries = this.$get('countries');
var countryNames = _.chain(countries).pluck('name');
var textMatched = function (val) {
var re = new w.RegExp('.*' + text + '.*', 'i');
return re.test(val);
};
var suggestedCommonNames = countryNames
.pluck('common')
.filter(textMatched)
.value();
var suggestedOfficialNames = countryNames
.pluck('official')
.filter(textMatched)
.value();
var suggestedNames = _.union(suggestedCommonNames, suggestedOfficialNames);
var suggestedCountries = _.chain(suggestedNames)
.map(function (suggestedName) {
var index = countryNames
.findIndex(function (name) {
return name.common === suggestedName || name.official === suggestedName;
})
.value();
return countries[index];
})
.value();
this.$broadcast('lookup:broadcast', suggestedCountries);
this.$emit('lookup', suggestedCountries);
}
}
});
/** Google Maps */
var mapCanvas = d.createElement('div');
mapCanvas.setAttribute('id', 'map-canvas');
var latLng = new GM.LatLng(35.6833, 139.6833);
var map = new GM.Map(mapCanvas, { center: latLng, zoom: 10 });
var mapReset = function (center, zoom) {
GM.event.trigger(map, 'resize');
map.setCenter(center || map.getCenter());
map.setZoom(zoom || map.getZoom());
};
/** JSON datas */
var countriesLoaded = $.get('//cdn.rawgit.com/mledoze/countries/master/dist/countries.json');
var activeCountryLoaded = function (code) {
var url = '//cdn.rawgit.com/mledoze/countries/master/data/' + code + '.geo.json';
return $.get(url);
};
/** Main process */
var polygon = function (coordinates) {
var polygons = _.map(coordinates, function (coords) {
var paths = _.chain(coords)
.map(function (coord) { return new GM.LatLng(coord[1], coord[0]); })
.value();
var polygon = new GM.Polygon({
paths: paths,
strokeColor: '#FF0000',
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35
});
return polygon;
});
return polygons;
};
var geojsonToPolygons = function (data) {
var features = _.chain(data.features)
.map(function (feature) {
var geometry = feature.geometry, polygons = [];
if (_.isEmpty(geometry) || !geometry.type) {
console.warn('Invalid data.');
} else if ('MultiPolygon' === geometry.type) {
polygons = polygon(geometry.coordinates);
} else if ('Polygon' === geometry.type) {
polygons = polygon(geometry.coordinates);
}
return polygons;
})
.value();
return features[0];
};
var main = function (doc, countries) {
nav.$mount('#nav');
nav.$set('countries', countries[0]);
var ___polygons = [];
nav.$on('lookup', function (countries) {
_.each(___polygons, function (polygon) { polygon.setMap(null); });
___polygons = [];
_.each(countries, function (country) {
activeCountryLoaded(country.cca3.toLowerCase()).then(function (resp) {
___polygons = geojsonToPolygons(resp);
_.each(___polygons, function (polygon) { polygon.setMap(map); });
}, error);
});
var firstCountry = _.first(countries);
if (!_.isEmpty(firstCountry)) {
var latLng = new GM.LatLng(firstCountry.latlng[0], firstCountry.latlng[1]);
map.panTo(latLng);
}
});
d.body.appendChild(mapCanvas);
mapCanvas.style.position = 'absolute';
mapReset(latLng, 3);
};
var error = function (err) {
console.error(err.message);
};
var promises = [
documentLoaded(),
countriesLoaded
];
$.when.apply(undefined, promises).then(main, error);
})(window, document, navigator, _, jQuery, Vue, google.maps);
</script>
</head>
<body>
<nav id="nav">
<autocomplete-input-box></autocomplete-input-box>
</nav>
</body>
</html>
@japboy
Copy link
Author

japboy commented Jun 11, 2015

@Joshfindit
Copy link

Looks like the API key is expired; console shows:

Google Maps API error: ExpiredKeyMapError https://developers.google.com/maps/documentation/javascript/error-messages#expired-key-map-error         js?key=AIzaSyDCkYB76QzhTAx26dDiRP2l6pe2cqVZ3PY:34
_.kb                 @ js?key=AIzaSyDCkYB76QzhTAx26dDiRP2l6pe2cqVZ3PY:34
(anonymous function) @ common.js:50
(anonymous function) @ common.js:200
c                    @ common.js:44
(anonymous function) @ AuthenticationService.Authenticate?1shttp%3A%2F%2Fbl.ocks.org%2Fjapboy%2Fraw%2Fefb780b……:1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment