I'm appending a Search Results to the google places javascript api autocomplete.
So far I'm doing this:
var autocomplete;
function initialize() {
var myLatlng = new google.maps.LatLng(40.738793, -73.991402);
autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'));
}
later on I have this:
$('.pac-container').append( '<div class="j-search pac-item-refresh">Search Results</div>' );
$(document.body).on('click', '.pac-container .j-search', function(e) {
console.log('click fired');
});
The problem? The click event never fires...
Any idea why? Anything wrong with my code?
It seems that the click-event for .pac-container is cancelled by the Autocomplete-instance. Use mousedown instead.
You can follow the this article.
Implement and Optimize Autocomplete with Google Places API
Specifically Autocompletion using the AutocompleteService:
link: JS Filddle Of AutocompletionService
function debounce(func, wait, immediate) {
let timeout;
return function() {
let context = this,
args = arguments;
let later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
function initAutocomplete() {
let map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 48,
lng: 4
},
zoom: 4,
disableDefaultUI: true
});
// Create the search box and link it to the UI element.
let inputContainer = document.querySelector('autocomplete-input-container');
let autocomplete_results = document.querySelector('.autocomplete-results');
let service = new google.maps.places.AutocompleteService();
let serviceDetails = new google.maps.places.PlacesService(map);
let marker = new google.maps.Marker({
map: map
});
let displaySuggestions = function(predictions, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
let results_html = [];
predictions.forEach(function(prediction) {
results_html.push(`<li class="autocomplete-item" data-type="place" data-place-id=${prediction.place_id}><span class="autocomplete-icon icon-localities"></span> <span class="autocomplete-text">${prediction.description}</span></li>`);
});
autocomplete_results.innerHTML = results_html.join("");
autocomplete_results.style.display = 'block';
let autocomplete_items = autocomplete_results.querySelectorAll('.autocomplete-item');
for (let autocomplete_item of autocomplete_items) {
autocomplete_item.addEventListener('click', function() {
let prediction = {};
const selected_text = this.querySelector('.autocomplete-text').textContent;
const place_id = this.getAttribute('data-place-id');
let request = {
placeId: place_id,
fields: ['name', 'geometry']
};
serviceDetails.getDetails(request, function(place, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var bounds = new google.maps.LatLngBounds();
marker.setPosition(place.geometry.location);
if (place.geometry.viewport) {
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
}
autocomplete_input.value = selected_text;
autocomplete_results.style.display = 'none';
});
})
}
};
let autocomplete_input = document.getElementById('my-input-autocomplete');
autocomplete_input.addEventListener('input', debounce(function() {
let value = this.value;
value.replace('"', '\\"').replace(/^\s+|\s+$/g, '');
if (value !== "") {
service.getPlacePredictions({
input: value
}, displaySuggestions);
} else {
autocomplete_results.innerHTML = '';
autocomplete_results.style.display = 'none';
}
}, 150));
}
document.addEventListener("DOMContentLoaded", function(event) {
initAutocomplete();
});
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.autocomplete-input-container {
position: absolute;
z-index: 1;
width: 100%;
}
.autocomplete-input {
text-align: center;
}
#my-input-autocomplete {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
font-size: 15px;
border-radius: 3px;
border: 0;
margin-top: 10px;
width: 290px;
height: 40px;
text-overflow: ellipsis;
padding: 0 1em;
}
#my-input-autocomplete:focus {
outline: none;
}
.autocomplete-results {
margin: 0 auto;
right: 0;
left: 0;
position: absolute;
display: none;
background-color: white;
width: 320px;
padding: 0;
list-style-type: none;
margin: 0 auto;
border: 1px solid #d2d2d2;
border-top: 0;
box-sizing: border-box;
}
.autocomplete-item {
padding: 5px 5px 5px 35px;
height: 26px;
line-height: 26px;
border-top: 1px solid #d9d9d9;
position: relative;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.autocomplete-icon {
display: block;
position: absolute;
top: 7px;
bottom: 0;
left: 8px;
width: 20px;
height: 20px;
background-repeat: no-repeat;
background-position: center center;
}
.autocomplete-icon.icon-localities {
background-image: url(https://images.woosmap.com/icons/locality.svg);
}
.autocomplete-item:hover .autocomplete-icon.icon-localities {
background-image: url(https://images.woosmap.com/icons/locality-selected.svg);
}
.autocomplete-item:hover {
background-color: #f2f2f2;
cursor: pointer;
}
.autocomplete-results::after {
content: "";
padding: 1px 1px 1px 0;
height: 18px;
box-sizing: border-box;
text-align: right;
display: block;
background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3_hdpi.png);
background-position: right;
background-repeat: no-repeat;
background-size: 120px 14px
}
<div class="autocomplete-input-container">
<div class="autocomplete-input">
<input id="my-input-autocomplete" placeholder="AutocompleteService" autocomplete="off" role="combobox">
</div>
<ul class="autocomplete-results">
</ul>
</div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback"></script>
Related
I have an application that I have written that adds a set of traffic lights on the screen upon the press of a button. The traffic light automatically cycles from red to yellow after 10 seconds, then on to green after two seconds, then back to yellow after 10 seconds and finally back to red. I have added a control which allows the user to start each traffic light individually. I am trying to figure out how to enable the user to permanently stop each traffic light, without it stopping all the others.
Here is my updated code so far - note the addition of the 'this.stop()' function inside of var Red. I would like the code to stop the rotation there, rather than continue to yellow and green.
Thanks,
Rob
var i = 1;
var TrafficLight = function(i) {
var count = 0;
var light_container = document.getElementById('light-container-' + i);
var currentState = new Red(this, light_container);
this.change = function(state) {
currentState = state;
currentState.go();
}
this.start = function() {
currentState.go();
}
this.stop = function() {
currentState.stop();
}
}
var Red = function(light, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#d8412c';
console.log(light_container);
setTimeout(function() {
light.change(new Yellow(light, 'red', light_container))
}, 12000);
}
this.stop = function() {
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#111111';
// Switch all the lights off.
return;
}
}
var Yellow = function(light, origin, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#fad201';
setTimeout(function() {
if (origin == 'red') {
light.change(new Green(light, light_container));
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
} else if (origin == 'green') {
light.change(new Red(light, light_container));
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
}
}, 2000);
}
}
var Green = function(light, light_container) {
this.light = light;
console.log('here');
this.go = function() {
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#33A532';
setTimeout(function() {
light.change(new Yellow(light, 'green', light_container))
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#111111';
}, 14000);
}
};
function initiate() {
var light_container = document.createElement('div');
light_container.id = "light-container-" + i;
light_container.className = "light-container";
light_container.innerHTML = '<div class="outer-circle-red"><div class="inner-circle-red"></div></div><div class="outer-circle-yellow"><div class="inner-circle-yellow"></div></div><div class="outer-circle-green"><div class="inner-circle-green"></div></div><label class="switch"><input type="checkbox" class="off" onclick="toggleRun(this, ' + i + ');"><span class="slider round"></span></label>';
document.getElementById("container").appendChild(light_container);
i++;
}
function toggleRun(item, i) {
if (item.className == "off") {
item.className = "on";
run(i);
} else {
item.className = "off";
stop(i);
}
}
function run(i) {
var light = new TrafficLight(i);
light.start();
}
function stop(i) {
var light = new TrafficLight(i);
light.stop();
}
function exit(status) {
var i;
if (typeof status === 'string') {
alert(status);
}
window.addEventListener('error', function(e) {
e.preventDefault();
e.stopPropagation();
}, false);
var handlers = [
'copy', 'cut', 'paste',
'beforeunload', 'blur', 'change', 'click', 'contextmenu', 'dblclick', 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize', 'scroll',
'DOMNodeInserted', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument', 'DOMNodeInsertedIntoDocument', 'DOMAttrModified', 'DOMCharacterDataModified', 'DOMElementNameChanged', 'DOMAttributeNameChanged', 'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', 'online', 'offline', 'textInput',
'abort', 'close', 'dragdrop', 'load', 'paint', 'reset', 'select', 'submit', 'unload'
];
function stopPropagation(e) {
e.stopPropagation();
// e.preventDefault(); // Stop for the form controls, etc., too?
}
for (i = 0; i < handlers.length; i++) {
window.addEventListener(handlers[i], function(e) {
stopPropagation(e);
}, true);
}
if (window.stop) {
window.stop();
}
throw '';
}
#button {
width: 200px;
height: 20px;
padding: 10px;
background-color: blue;
color: #ffffff;
cursor: pointer;
}
.button {
width: 15px;
height: 20px;
padding: 10px;
background-color: red;
color: #ffffff;
cursor: pointer;
margin: 20px auto;
text-align: center;
text-transform: uppercase;
font-weight: bold;
}
.outer-circle-red,
.outer-circle-yellow,
.outer-circle-green {
background-color: #696969;
margin: 0 auto;
border: 2px solid black;
width: 50px;
height: 40px;
border-radius: 15px;
display: table;
}
.light-container {
margin: 20px 30px 0 30px;
margin-top: 20px;
float: left;
}
.inner-circle-red,
.inner-circle-yellow,
.inner-circle-green {
width: 20px;
height: 20px;
border-radius: 25px;
border: 2px solid #111111;
margin: 0 auto;
margin-top: 7.5px;
background-color: #111111;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
margin-top: 20px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #2196F3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
<div id="button" onclick="initiate()">+ Add a new traffic light</div>
<div id="container">
</div>
The solution to this is to save the id returned by var id = setTimeout(), so you can use clearTimeout( id ); later on to completely stop the timeout function from triggering again.
So something like: this.timeout = setInterval(function(){ /* insert the color changing code */ }, 10000 );.
If you opt for such a solution, it would be handy to put the timeout code into a single timeout instead of having a separate class for each color. But you can always use an array to store all timeouts and loop over that to cancel if you like having different timeouts for each color.
I want to customize auto suggestion result. I want to add more two addresses at the top of the result. Is it possible using google api?
for more understanding I stick here my app screen. there I am entering address. it showing predicted addresses, How can I add 2 more address at top of the result.
You can't do much with the Autocomplete class, at least not with any documented method. You can use the Autocomplete Service class and the getPlacePredictions method to mimic the behavior of the standard Autocomplete.
What that means is that you will have to build your own UI and behaviors, but it also gives you more flexibility to style it the way you want, and it will allow you to add your custom addresses easily.
Here is a quick example. It just adds two custom addresses on top. You will have to implement the logic behind the 2 custom addresses as currently nothing will happen when you click on them. But that's not the trickiest part, and this example shows already a lot of what you can do with it.
var autocompleteService, placesService, results, map;
function initialize() {
results = document.getElementById('results');
var mapOptions = {
zoom: 5,
center: new google.maps.LatLng(50, 50)
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// Bind listener for address search
google.maps.event.addDomListener(document.getElementById('address'), 'input', function() {
results.style.display = 'block';
getPlacePredictions(document.getElementById('address').value);
});
// Show results when address field is focused (if not empty)
google.maps.event.addDomListener(document.getElementById('address'), 'focus', function() {
if (document.getElementById('address').value !== '') {
results.style.display = 'block';
getPlacePredictions(document.getElementById('address').value);
}
});
// Hide results when click occurs out of the results and inputs
google.maps.event.addDomListener(document, 'click', function(e) {
if ((e.target.parentElement.className !== 'pac-container') && (e.target.parentElement.className !== 'pac-item') && (e.target.tagName !== 'INPUT')) {
results.style.display = 'none';
}
});
autocompleteService = new google.maps.places.AutocompleteService();
placesService = new google.maps.places.PlacesService(map);
}
// Get place predictions
function getPlacePredictions(search) {
autocompleteService.getPlacePredictions({
input: search,
types: ['establishment', 'geocode']
}, callback);
}
// Get place details
function getPlaceDetails(placeId) {
var request = {
placeId: placeId
};
placesService.getDetails(request, function(place, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
var center = place.geometry.location;
var marker = new google.maps.Marker({
position: center,
map: map
});
map.setCenter(center);
// Hide autocomplete results
results.style.display = 'none';
}
});
}
// Place search callback
function callback(predictions, status) {
// Empty results container
results.innerHTML = '';
// Place service status error
if (status != google.maps.places.PlacesServiceStatus.OK) {
results.innerHTML = '<div class="pac-item pac-item-error">Your search returned no result. Status: ' + status + '</div>';
return;
}
// Build output with custom addresses
results.innerHTML += '<div class="pac-item custom"><span class="pac-icon pac-icon-marker"></span>My home address</div>';
results.innerHTML += '<div class="pac-item custom"><span class="pac-icon pac-icon-marker"></span>My work address</div>';
// Build output for each prediction
for (var i = 0, prediction; prediction = predictions[i]; i++) {
// Insert output in results container
results.innerHTML += '<div class="pac-item" data-placeid="' + prediction.place_id + '" data-name="' + prediction.terms[0].value + '"><span class="pac-icon pac-icon-marker"></span>' + prediction.description + '</div>';
}
var items = document.getElementsByClassName("pac-item");
// Results items click
for (var i = 0, item; item = items[i]; i++) {
item.onclick = function() {
if (this.dataset.placeid) {
getPlaceDetails(this.dataset.placeid);
}
};
}
}
google.maps.event.addDomListener(window, 'load', initialize);
body,
html {
font-family: Arial, sans-serif;
padding: 0;
margin: 0;
height: 100%;
}
#map-canvas {
height: 130px;
margin-bottom: 10px;
}
table {
border-collapse: collapse;
margin-left: 20px;
}
table td {
padding: 3px 5px;
}
label {
display: inline-block;
width: 160px;
font-size: 11px;
color: #777;
}
input {
border: 1px solid #ccc;
width: 170px;
padding: 3px 5px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-shadow: 0 2px 6px rgba(0, 0, 0, .1);
}
.pac-container {
background-color: #fff;
z-index: 1000;
border-radius: 2px;
font-size: 11px;
box-shadow: 0 2px 6px rgba(0, 0, 0, .3);
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
width: 350px;
}
.pac-icon {
width: 15px;
height: 20px;
margin-right: 7px;
margin-top: 6px;
display: inline-block;
vertical-align: top;
background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/autocomplete-icons.png);
background-size: 34px;
}
.pac-icon-marker {
background-position: -1px -161px;
}
.pac-item {
cursor: pointer;
padding: 0 4px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
line-height: 30px;
vertical-align: middle;
text-align: left;
border-top: 1px solid #e6e6e6;
color: #999;
}
.pac-item.custom {
background-color: #FFF9C4;
}
.pac-item:hover {
background-color: #efefef;
}
.pac-item-error,
.pac-item-error:hover {
color: #aaa;
padding: 0 5px;
cursor: default;
background-color: #fff;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script src="//maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas"></div>
<table>
<tr>
<td>
<label for="address">Address:</label>
</td>
</tr>
<tr>
<td>
<input id="address" placeholder="Enter address" type="text" tabindex="1" />
</td>
</tr>
<tr>
<td colspan="2">
<div id="results" class="pac-container"></div>
</td>
</tr>
</table>
Most of the code is commented so it should speak for itself.
JSFiddle demo
In case anyone needs to move through the results with arrow keys, I've written something like this in addition to the example provided by MrUpsidown.
Functions nextAll and prevAll can be probably simplified to next and prev, but I had to use these as I have some dividing elements of different classes (than .pac-item) in the results.
// move through options on key down or up
$(input).keydown(function(e) {
switch (e.which) {
case 40: // move down
e.preventDefault(); // prevent moving the cursor
if(document.querySelector('.pac-item-selected') == null)
$('.pac-item').first().addClass('pac-item-selected');
else {
var i = $('.pac-item:not(:last-child).pac-item-selected').nextAll('.pac-item');
if(i.length > 0){
$('.pac-item:not(:last-child).pac-item-selected').removeClass('pac-item-selected');
i[0].classList.add('pac-item-selected');
}
}
break;
case 38: // move up
e.preventDefault(); // prevent moving the cursor
var i = $('.pac-item:not(:first-child).pac-item-selected').prevAll('.pac-item');
if(i.length > 0){
$('.pac-item:not(:first-child).pac-item-selected').removeClass('pac-item-selected');
i[0].classList.add('pac-item-selected');
}
break;
case 13: // submit when enter is pressed
e.preventDefault();
if(document.querySelector('.pac-item-selected') == null)
$('.pac-item').first().click();
else
$('.pac-item-selected').click();
break;
}
});
$(document).on({ // remove selected class on hover
mouseenter: function () {
$('.pac-item-selected').removeClass('pac-item-selected');
}
}, ".pac-item");
Google Maps Traffic Widget
i want to show the widget from the picture above in my embedded map to show typical traffic. but i can't seem to find any documentation for this. this is my current javascript code
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 17,
clickableIcons: false,
center: {lat: 34.04924594193164, lng: -118.24104309082031}
});
var myMarker = new google.maps.Marker({
position: {lat: 34.04924594193164, lng: -118.24104309082031},
map: map,
title: 'myMarker',
draggable: false
});
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
}
Exactly what you want is not provided in official document.
You can create custom legends base on this tutorial
function initMap() {
var options = {
zoom: 13,
center: {lat: 34.04924594193164, lng: -118.24104309082031},
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-container'), options);
//var trafficLayer = new google.maps.TrafficLayer();
//trafficLayer.setMap(map);
var controlDiv = document.createElement('DIV');
$(controlDiv).addClass('gmap-control-container')
.addClass('gmnoprint');
var controlUI = document.createElement('DIV');
$(controlUI).addClass('gmap-control');
$(controlUI).text('Traffic');
$(controlDiv).append(controlUI);
var legend = '<ul>'
+ '<li><span style="background-color: #30ac3e"> </span><span style="color: #30ac3e"> > 80 km per hour</span></li>'
+ '<li><span style="background-color: #ffcf00"> </span><span style="color: #ffcf00"> 40 - 80 km per hour</span></li>'
+ '<li><span style="background-color: #ff0000"> </span><span style="color: #ff0000"> < 40 km per hour</span></li>'
+ '<li><span style="background-color: #c0c0c0"> </span><span style="color: #c0c0c0"> No data available</span></li>'
+ '</ul>';
var controlLegend = document.createElement('DIV');
$(controlLegend).addClass('gmap-control-legend');
$(controlLegend).html(legend);
$(controlLegend).hide();
$(controlDiv).append(controlLegend);
// Set hover toggle event
$(controlUI)
.mouseenter(function() {
$(controlLegend).show();
})
.mouseleave(function() {
$(controlLegend).hide();
});
var trafficLayer = new google.maps.TrafficLayer();
google.maps.event.addDomListener(controlUI, 'click', function() {
if (typeof trafficLayer.getMap() == 'undefined' || trafficLayer.getMap() === null) {
$(controlUI).addClass('gmap-control-active');
trafficLayer.setMap(map);
} else {
trafficLayer.setMap(null);
$(controlUI).removeClass('gmap-control-active');
}
});
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(controlDiv);
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map-container {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.gmap-control-container {
margin: 5px;
}
.gmap-control {
cursor: pointer;
background-color: -moz-linear-gradient(center top , #FEFEFE, #F3F3F3);
background-color: #FEFEFE;
border: 1px solid #A9BBDF;
border-radius: 2px;
padding: 0 6px;
line-height: 160%;
font-size: 12px;
font-family: Arial,sans-serif;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.35);
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;
}
.gmap-control:hover {
border: 1px solid #678AC7;
}
.gmap-control-active {
background-color: -moz-linear-gradient(center top , #6D8ACC, #7B98D9);
background-color: #6D8ACC;
color: #fff;
font-weight: bold;
border: 1px solid #678AC7;
}
.gmap-control-legend {
position: absolute;
text-align: left;
z-index: -1;
top: 20px;
right: 0;
width: 150px;
height: 66px;
font-size: 10px;
background: #FEFEFE;
border: 1px solid #A9BBDF;
padding: 10px;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.35);
}
.gmap-control-legend ul {
margin: 0;
padding: 0;
list-style-type: none;
}
.gmap-control-legend li {
line-height: 160%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="map-container"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>
I've created the following fiddle https://jsfiddle.net/jnoweb/v421zzbe/2/
At the moment it has one variable which makes all three IDs count up to 20:
var game = {score:0},
scoreDisplay = [
document.getElementById("score1"),
document.getElementById("score2"),
document.getElementById("score3")];
function add20() {
TweenLite.to(game, 1, {score:"+=20", roundProps:"score", onUpdate:updateHandler, ease:Linear.easeNone});
}
function updateHandler() {
scoreDisplay.forEach(function(display) {
display.innerHTML = game.score;
});
}
add20();
I want to change this so that each ID counts to a different value, for example 16, 18 and 20!
Does anyone know how to achieve this?
Here is the more elegant, generic, configurable solution.
function ScoreDisplay(id, increment) {
this.elm = document.getElementById(id);
this.inc = increment;
this.game = {score: 0};
}
ScoreDisplay.prototype = {
update: function(){
this.elm.innerHTML = this.game.score;
}
};
var scoreDisplay = [];
scoreDisplay.push(new ScoreDisplay('score1', 16));
scoreDisplay.push(new ScoreDisplay('score2', 18));
scoreDisplay.push(new ScoreDisplay('score3', 20));
function addScore() {
scoreDisplay.forEach(function(sd) {
TweenLite.to(sd.game, 1, {score: "+=" + sd.inc, roundProps:"score", onUpdate:sd.update.bind(sd), ease:Linear.easeNone});
});
}
addScore();
#score1 {
position: relative;
font-size: 30px;
font-weight: bold;
padding: 20px;
text-align: center;
background-color: transparent;
color: $white;
border-radius: 20px 20px;
top: -11px;
left: -42px;
}
#score2 {
position: relative;
font-size: 30px;
font-weight: bold;
padding: 20px;
text-align: center;
background-color: transparent;
color: $white;
border-radius: 20px 20px;
top: -11px;
left: -42px;
}
#score3 {
position: relative;
font-size: 30px;
font-weight: bold;
padding: 20px;
text-align: center;
background-color: transparent;
color: $white;
border-radius: 20px 20px;
top: -11px;
left: -42px;
}
<!--TweenLite/TweenMax GSAP-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/CSSPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/easing/EasePack.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenLite.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TimelineLite.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/RoundPropsPlugin.min.js"></script>
<div id="prodArrow"></div>
<div id="prodCount">
<div id="score1"></div>
</div>
<div id="testArrow"></div>
<div id="testCount">
<div id="score2"></div>
</div>
<div id="devArrow"></div>
<div id="devCount">
<div id="score3"></div>
</div>
var game = {
score1: 0,
score2: 0,
score3: 0
},
scoreDisplay = [
document.getElementById("score1"),
document.getElementById("score2"),
document.getElementById("score3")
];
function add(scoreIndex, numToAdd) {
TweenLite.to(game, 1, {score:("+="+numToAdd), roundProps: ("score" + scoreIndex), onUpdate:updateHandler, ease:Linear.easeNone});
}
function updateHandler() {
scoreDisplay.forEach(function(display, i) {
var key = ("score" + (i+1))
display.innerHTML = game[key];
});
}
add(1 , 16);
add(2 , 18);
add(3 , 20);
What about this ?
var game = {
score1:0,
score2:0,
score3:0
},
scoreDisplay = [
document.getElementById("score1"),
document.getElementById("score2"),
document.getElementById("score3")];
function add20() {
TweenLite.to(game, 1, {score1:"+=16", score2:"+=18", score3:"+=20", roundProps:"score", onUpdate:updateHandler, ease:Linear.easeNone});
}
function updateHandler() {
scoreDisplay.forEach(function(display, key) {
var score = scoreDisplay[key].id;
display.innerHTML = game[score];
});
}
add20();
https://jsfiddle.net/hundma4g/
i need to make a restaurant finder.. but to do that i need to be able to locate my users.. i have been having a hard time figuring out on how to geolocate them and pinpoint their location on the map and find restaurants near them..please help me.. i am new to this
First js code
var map, places, iw;
var markers = [];
var searchTimeout;
var centerMarker;
var autocomplete;
var hostnameRegexp = new RegExp('^https?://.+?/');
function initialize() {
var myLatlng = new google.maps.LatLng(37.786906, -122.410156);
var myOptions = {
zoom: 15,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
places = new google.maps.places.PlacesService(map);
google.maps.event.addListener(map, 'tilesloaded', tilesLoaded);
document.getElementById('keyword').onkeyup = function(e) {
if (!e) var e = window.event;
if (e.keyCode != 13) return;
document.getElementById('keyword').blur();
search(document.getElementById('keyword').value);
}
var typeSelect = document.getElementById('type');
typeSelect.onchange = function() {
search();
};
var rankBySelect = document.getElementById('rankBy');
rankBySelect.onchange = function() {
search();
};
}
function tilesLoaded() {
search();
google.maps.event.clearListeners(map, 'tilesloaded');
google.maps.event.addListener(map, 'zoom_changed', searchIfRankByProminence);
google.maps.event.addListener(map, 'dragend', search);
}
function searchIfRankByProminence() {
if (document.getElementById('rankBy').value == 'prominence') {
search();
}
}
function search() {
clearResults();
clearMarkers();
if (searchTimeout) {
window.clearTimeout(searchTimeout);
}
searchTimeout = window.setTimeout(reallyDoSearch, 500);
}
function reallyDoSearch() {
var type = document.getElementById('type').value;
var keyword = document.getElementById('keyword').value;
var rankBy = document.getElementById('rankBy').value;
var search = {};
if (keyword) {
search.keyword = keyword;
}
if (type != 'establishment') {
search.types = [type];
}
if (rankBy == 'distance' && (search.types || search.keyword)) {
search.rankBy = google.maps.places.RankBy.DISTANCE;
search.location = map.getCenter();
centerMarker = new google.maps.Marker({
position: search.location,
animation: google.maps.Animation.DROP,
map: map
});
} else {
search.bounds = map.getBounds();
}
places.search(search, function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
var icon = 'number_' + (i + 1) + '.png';
markers.push(new google.maps.Marker({
position: results[i].geometry.location,
animation: google.maps.Animation.DROP,
icon: icon
}));
google.maps.event.addListener(markers[i], 'click', getDetails(results[i], i));
window.setTimeout(dropMarker(i), i * 100);
addResult(results[i], i);
}
}
});
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
if (centerMarker) {
centerMarker.setMap(null);
}
}
function dropMarker(i) {
return function() {
if (markers[i]) {
markers[i].setMap(map);
}
}
}
function addResult(result, i) {
var results = document.getElementById('results');
var tr = document.createElement('tr');
tr.style.backgroundColor = (i % 2 == 0 ? '#F0F0F0' : '#FFFFFF');
tr.onclick = function() {
google.maps.event.trigger(markers[i], 'click');
};
var iconTd = document.createElement('td');
var nameTd = document.createElement('td');
var icon = document.createElement('img');
icon.src = 'number_' + (i + 1) + '.png';
icon.setAttribute('class', 'placeIcon');
icon.setAttribute('className', 'placeIcon');
var name = document.createTextNode(result.name);
iconTd.appendChild(icon);
nameTd.appendChild(name);
tr.appendChild(iconTd);
tr.appendChild(nameTd);
results.appendChild(tr);
}
function clearResults() {
var results = document.getElementById('results');
while (results.childNodes[0]) {
results.removeChild(results.childNodes[0]);
}
}
function getDetails(result, i) {
return function() {
places.getDetails({
reference: result.reference
}, showInfoWindow(i));
}
}
function showInfoWindow(i) {
return function(place, status) {
if (iw) {
iw.close();
iw = null;
}
if (status == google.maps.places.PlacesServiceStatus.OK) {
iw = new google.maps.InfoWindow({
content: getIWContent(place)
});
iw.open(map, markers[i]);
}
}
}
function getIWContent(place) {
var content = '';
content += '<table>';
content += '<tr class="iw_table_row">';
content += '<td style="text-align: left"><img class="hotelIcon" src="' + place.icon + '"/></td>';
content += '<td><b>' + place.name + '</b></td></tr>';
content += '<tr class="iw_table_row"><td class="iw_attribute_name">Address:</td><td>' + place.vicinity + '</td></tr>';
if (place.formatted_phone_number) {
content += '<tr class="iw_table_row"><td class="iw_attribute_name">Telephone:</td><td>' + place.formatted_phone_number + '</td></tr>';
}
if (place.rating) {
var ratingHtml = '';
for (var i = 0; i < 5; i++) {
if (place.rating < (i + 0.5)) {
ratingHtml += '✩';
} else {
ratingHtml += '✭';
}
}
content += '<tr class="iw_table_row"><td class="iw_attribute_name">Rating:</td><td><span id="rating">' + ratingHtml + '</span></td></tr>';
}
if (place.website) {
var fullUrl = place.website;
var website = hostnameRegexp.exec(place.website);
if (website == null) {
website = 'http://' + place.website + '/';
fullUrl = website;
}
content += '<tr class="iw_table_row"><td class="iw_attribute_name">Website:</td><td>' + website + '</td></tr>';
}
content += '</table>';
return content;
}
google.maps.event.addDomListener(window, 'load', initialize);
<!-- begin snippet: js hide: false -->
html {
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(superb-seaside-restaurant-hd-wallpaper-506329.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
background-size: cover
}
#form {
font: 20px"Walkway SemiBold";
letter-spacing: 5px;
text-align: center;
padding-bottom: 3px;
padding-right: 4px;
padding-top: 3px;
height: 35%;
width: 50%;
background: #ccc;
margin-bottom: 10px;
/* Fallback for older browsers without RGBA-support */
background: rgba(204, 204, 204, 0.5);
float: left;
}
#header {
font: 20px"Josefin Slab";
letter-spacing: 10px;
background-color: #fff;
color: #000;
text-align: center;
margin-top: 3px;
padding: 5px;
width: 1255px;
background: #ccc;
margin-bottom: 10px;
/* Fallback for older browsers without RGBA-support */
background: rgba(204, 204, 204, 0.5);
}
#map_canvas {
-webkit-box-shadow: 0 0 10px #bfdeff;
-moz-box-shadow: 0 0 5px #bfdeff;
box-shadow: 0 0 7px #bfdeff;
float: right;
height: 500px;
width: 593px;
padding: 10px;
margin-right: 3px;
vertical-align: top;
}
#listing {
font: 18pt"Nilland";
letter-spacing: 5px;
text-align: center;
padding: 3px;
height: 500px;
width: 50%;
background: #ccc;
margin-bottom: 10px;
/* Fallback for older browsers without RGBA-support */
background: rgba(204, 204, 204, 0.5);
float: left;
}
#footer {
font: 18px"Nilland-Black";
letter-spacing: 10px;
background-color: #fff;
color: #000;
text-align: right;
padding: 5px;
height: 27px;
width: 1255px;
background: #ccc;
margin-top: 3px;
margin-bottom: 3px;
/* Fallback for older browsers without RGBA-support */
background: rgba(204, 204, 204, 0.5);
float: right;
}
.placeIcon {
width: 32px;
height: 37px;
margin: 4px;
}
.hotelIcon {
width: 24px;
height: 24px;
}
#resultsTable {
font: 16pt"Nilland-Black";
border-collapse: collapse;
width: 450px;
margin-left: 90px;
float: left;
background: rgba(204, 204, 204, 0.5);
}
#rating {
font-size: 13px;
font-family: Arial Unicode MS;
}
#keywordsLabel {
text-align: right;
width: 70px;
font-size: 14px;
padding: 4px;
position: absolute;
}
.iw_table_row {
height: 18px;
}
.iw_attribute_name {
font-weight: bold;
text-align: right;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Map</title>
<link href="working.css" rel="stylesheet" type="text/css" />
<script src="http://maps.google.com/maps/api/js?sensor=true&libraries=places"></script>
<script src="C:\Users\beesumbernice\Documents\html\html\whole.js"></script>
<script src="C:\Users\beesumbernice\Documents\html\html\this.js"></script>
</head>
<body>
<div id="header">
<h1>
HEADER
</h1>
</div>
<div id="form">
Keywords:
<input id="keyword" type="text" placeholder="Mexican,Italian,Chinese..." />
<div id="controls">
<span id="typeLabel">
Type:
</span>
<select id="type">
<option value="bar">Bars</option>
<option value="cafe">Cafe</option>
<option value="restaurant" selected="selected">Restaurants</option>
</select>
<span id="rankByLabel">
Rank by:
</span>
<select id="rankBy">
<option value="prominence">Prominence</option>
<option value="distance" selected="selected">Distance</option>
</select>
</div>
</div>
<div id="map_canvas"></div>
<div id="listing" style="overflow-y: scroll; height:453px;">
<table id="resultsTable">
<tbody id="results"></tbody>
</table>
</div>
<div id="footer">
Maps Icons Collection
<img src="C:\Users\beesumbernice\Documents\html\html\desktop\powered-by-google-on-non-white.png" height="16" width="104"></img>
</div>
</body>
</html>
Hope this code will help you out
var mapInterval;
if(navigator.geolocation) {
var intervalTime = 5; // 5 seconds inteerval
mapInterval = window.setInterval(function(){
navigator.geolocation.getCurrentPosition(function(position) {
map.setCenter(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
}, intervalTime*1000)
});
// Whenever you want to stop updating the location
// mapInterval
Try this:
<html>
<body>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<script>
function initialize(){
var mapOptions =
{
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 8
};
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var lat=position.coords.latitude;
var lng=position.coords.longitude;
var geolocate = new google.maps.LatLng(lat, lng);
map.setCenter(geolocate);
});
}
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<div id="map-canvas" style="width:300;height:300px;border:1px solid black;"> </div>
</body>
</html>
Check it out "HERE"