How to get function to run after previous function has executed - javascript

So I have been working on a website what gets some information from a google sheet cell and it uses that to color a google maps overlay. The problem i'm running into is that the map overlay seems to be running before the cell information is retrieved. I'm not sure how to get the map overlay to wait until it has the info it needs.
Ultimately i'm going to have to get multiple cell values so I don't want to call my map every time I run getCell() hence me not putting myMap() inside the done() of $.getJSON
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<style type="text/css">
</style>
<script>
/** This is the ID of the google sheet **/
//This is the google sheet ID of the google sheet with the graphs for the event.
var theSheetID = "1eAP6dugifHIHRSgnc8Mx-FdzriDBP5r0vn8yq0ShknA";
var typeOfEvent = "Event";
var eventManager = "Jeb";
var managerCell = "123-456-789";
//This is the google sheet ID of the google sheet with the lot values for the event.
var theMapSheetID = "1oUW8EvxlSMArW1qTQMxVJua1QrgCOgo5G545Jb4OZ-4";
var workSheetID = "default";
//duplicate these for every cell you are want to access
var theRow = "1";
var theColumn = "1";
//make duplicates of this variable for each lot you have
//i.e. lot
var theLot;
var theLot1;
//theLot=20;
$(document).ready(function() {
getCell = function() {
var api = 'https://spreadsheets.google.com/feeds/cells/';
var spreadsheet = theMapSheetID;
var worksheet = workSheetID;
var row = theRow;
var col = theColumn;
var row1 = 2;
var col2 = 2;
var url = api + spreadsheet + '/' + worksheet + '/public/basic/R' + row + 'C' + col + '?alt=json';
$.getJSON(url)
.done(function(data) {
console.log(data)
if (data.entry) {
theLot = parseInt(data.entry.content['$t']);
// return $.Deferred();
//myMap();
} else {}
})
.fail(function() {});
}
//$.when(getCell()).then(myMap());
//myMap();
});
</script>
<script>
function myMap() {
//theLot = 15;
var p1 = new google.maps.LatLng(41.051651, -75.515626);
var p2 = new google.maps.LatLng(41.048082, -75.521755);
var p3 = new google.maps.LatLng(41.048006, -75.522286);
var p4 = new google.maps.LatLng(41.051565, -75.5288822);
var p5 = new google.maps.LatLng(41.056059, -75.523349);
var p6 = new google.maps.LatLng(41.053316, -75.520697);
var mapCanvas = document.getElementById("map");
var mapOptions = {
center: p2,
zoom: 15
};
var map = new google.maps.Map(mapCanvas, mapOptions);
// var map = new google.maps.Map(document.getElementById("googleMap"),mapOptions);
var theColor;
//alert(theLot);
var myCenter = new google.maps.LatLng(41.051629, -75.522953);
var marker = new google.maps.Marker({
position: myCenter
});
marker.setMap(map);
var infowindow = new google.maps.InfoWindow({
content: theLot.toString()
});
infowindow.open(map, marker);
if (theLot < 25) {
theColor = "#ff0000";
} else if (theLot > 25 && theLot < 50) {
theColor = "#fff200";
} else if (theLot > 50 && theLot < 75) {
theColor = "#aaff00";
} else {
theColor = "#00ff00";
}
var lotOverlay = new google.maps.Polygon({
path: [p1, p2, p3, p4, p5, p6],
strokeColor: "#000000",
strokeOpacity: 0.0,
strokeWeight: 2,
fillColor: theColor,
fillOpacity: 0.5
});
lotOverlay.setMap(map);
}
</script>
<body>
<br />
<br />
<div class="container">
</div>
<br />
<div class="container" style="text-align:center; max-width: 42em;">
<div class="jumbotron">
<!-- Event Name -->
<div align="center">
<h2>Graduation 2017</h2>
<h4>Please contact us for more detailed information:</h4>
<script type="text/javascript">
document.write("<h4>" + typeOfEvent + " Manager: " + eventManager + "</h4><br />");
document.write(" <div class=\"row\"> Call &nbsp Text</div>");
</script>
</div>
</div>
<!-- Link to ELP -->
View Event Logistics Plan (ELP)
</div>
<hr width="100%" size="3" color="#0000FF" />
<div class="container" align="Center">
<div class="row">
<div class="col-lg-6">
<!-- Google Sheet Overview -->
<script type="text/javascript">
document.write("<iframe src=\"https://docs.google.com/spreadsheets/d/" + theSheetID + "/pubchart?oid=784983700&format=interactive&chrome=false\" width=\"600\" height =\"400\" frameborder=\"0\"></iframe>");
</script>
</div>
<div class="col-lg-6">
<!-- Google Sheet Flow -->
<script>
document.write("<iframe src=\"https://docs.google.com/spreadsheets/d/" + theSheetID + "/pubhtml?gid=225087979&single=true&headers=false&chrome=false\" width=\"600\" height =\"400\" frameborder=\"0\"></iframe>");
</script>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<!-- Google Sheet Deatils -->
<script>
document.write("<iframe src=\"https://docs.google.com/spreadsheets/d/" + theSheetID + "/pubhtml?gid=328375376&gridlines=false&range=a1:l20&chrome=false\" width = \"1000\" height =\"600\" frameborder=\"0\"></iframe>");
</script>
</div>
<div class="col-lg-12">
<div id="map" style="width:80%;height:500px"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBfWJMAiVJy9LcuMF_vogE_KawTRFaFxig&callback=myMap"></script>
</div>
</div>
</div>
<br />
<br />
</body>
</html>

JavaScript statements are executed line by line. However, with effects, the next line of code can be run even though the effect is not finished. This can create errors.
To prevent this, you can create a callback function. All it is, you can pass the function as an argument and it will be executed last.
$("button").click(function(){
$("p").hide("slow", function(){
alert("The paragraph is now hidden");
});
});
https://www.w3schools.com/jquery/jquery_callback.asp
if you gonna call it like that, then you can get an alert before hide is finished executing.
$("button").click(function(){
$("p").hide("slow");
alert("The paragraph is now hidden");
});

Related

Marker Clustering does not display

I am trying to cluster markers (each manually created) on my map using the Leaflet.markercluster plugin.
Does anybody know what I am doing incorrectly? I see the map and my two points but not the cluster of the two.
Additionally, I want to populate the map with many markers but it is not working. Thank you!
<!DOCTYPE html>
<html>
<head>
<!-- need jQuery for AJXA -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="screen.css" />
<link rel="stylesheet" href="../Desktop/MarkerCluster.css" />
<link rel="stylesheet" href="../Desktop/MarkerCluster.Default.css" />
<script src ="https://unpkg.com/browse/leaflet.markercluster#1.4.1/dist/leaflet.markercluster.js"></script>
<script src ="https://unpkg.com/browse/leaflet.markercluster#1.4.1/dist/MarkerCluster.css"></script>
<script src ="https://unpkg.com/browse/leaflet.markercluster#1.4.1/dist/MarkerCluster.Default.css"></script>
<!-- Code from https://github.com/macek/jquery-serialize-object -->
<script>
/**
* jQuery serializeObject
* #copyright 2014, macek <paulmacek#gmail.com>
* #link https://github.com/macek/jquery-serialize-object
* #license BSD
* #version 2.5.0
*/
! function(e, i) {
if ("function" == typeof define && define.amd) define(["exports", "jquery"], function(e, r) {
return i(e, r)
});
else if ("undefined" != typeof exports) {
var r = require("jquery");
i(exports, r)
} else i(e, e.jQuery || e.Zepto || e.ender || e.$)
}(this, function(e, i) {
function r(e, r) {
function n(e, i, r) {
return e[i] = r, e
}
function a(e, i) {
for (var r, a = e.match(t.key); void 0 !== (r = a.pop());)
if (t.push.test(r)) {
var u = s(e.replace(/\[\]$/, ""));
i = n([], u, i)
} else t.fixed.test(r) ? i = n([], r, i) : t.named.test(r) && (i = n({}, r, i));
return i
}
function s(e) {
return void 0 === h[e] && (h[e] = 0), h[e]++
}
function u(e) {
switch (i('[name="' + e.name + '"]', r).attr("type")) {
case "checkbox":
return "on" === e.value ? !0 : e.value;
default:
return e.value
}
}
function f(i) {
if (!t.validate.test(i.name)) return this;
var r = a(i.name, u(i));
return l = e.extend(!0, l, r), this
}
function d(i) {
if (!e.isArray(i)) throw new Error("formSerializer.addPairs expects an Array");
for (var r = 0, t = i.length; t > r; r++) this.addPair(i[r]);
return this
}
function o() {
return l
}
function c() {
return JSON.stringify(o())
}
var l = {},
h = {};
this.addPair = f, this.addPairs = d, this.serialize = o, this.serializeJSON = c
}
var t = {
validate: /^[a-z_][a-z0-9_]*(?:\[(?:\d*|[a-z0-9_]+)\])*$/i,
key: /[a-z0-9_]+|(?=\[\])/gi,
push: /^$/,
fixed: /^\d+$/,
named: /^[a-z0-9_]+$/i
};
return r.patterns = t, r.serializeObject = function() {
return new r(i, this).addPairs(this.serializeArray()).serialize()
}, r.serializeJSON = function() {
return new r(i, this).addPairs(this.serializeArray()).serializeJSON()
}, "undefined" != typeof i.fn && (i.fn.serializeObject = r.serializeObject, i.fn.serializeJSON = r.serializeJSON), e.FormSerializer = r, r
});
</script>
<div id="left">
<div id="google-form">
<form action="https://docs.google.com/forms/d/e/1FAIpQLSe3K5mmm5Fzezpltxb0dmElMxJYMpyMkujwPjbjPbiGRa1MPQ/viewform?usp=sf_link" target="hiddenFrame">
<iframe name="hiddenFrame" width="0" height="0" border="0" style="display: none;"></iframe>
<h2>Tell us about a time you cried at Yale.</h2>
<p class="caption">Responses may be edited for clarity and length.</p>
<textarea jsname="YPqjbf" jscontroller="gZjhIf" jsaction="input:Lg5SV;ti6hGc:XMgOHc;rcuQ6b:WYd;" required="" name="entry.643682983" dir="auto" data-initial-dir="auto"></textarea>
<div id="buttons">
<input type="button" id="drag" value="Add pin to map" name="entry.2117530617">
<input id="location" type="text" jsname="YPqjbf" autocomplete="off" tabindex="0" name="entry.2117530617" value="" required="" dir="auto" data-initial-dir="auto" data-initial-value="" style="display: none">
<input class="button" id="submit" type="submit" value="Submit" disabled="true">
</div>
</form>
</div>
</div>
<style>
#map {
position: absolute;
top: 0;
bottom: 0;
left: 30%;
right: 0;
}
</style>
<script>
</script>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js">
</script>
<div class="marker-menu">
<img class="draggable-marker" src="images/marker-icon.png" alt="marker" />
</div>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var tiles = L.tileLayer('https://api.maptiler.com/maps/streets/256/{z}/{x}/{y}.png?key=wZnhwGRqtomo0QHvxpxW', {
maxZoom: 18,
attribution: '© OpenStreetMap contributors'
}),
latlng = L.latLng(41.310970, -72.931990);
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]});
var markers = L.marker([41.310253,-72.92642]);
map.addLayer(markers);
var markers = L.marker([41.310970, -72.931992]);
map.addLayer(markers);
var markers = L.markerClusterGroup();
markers.on('clusterclick', function (a) {
a.layer.spiderfy();
});
function populate() {
for (var i = 0; i < 1000; i++) {
var m = L.marker(getRandomLatLng(map));
markers.addLayer(m);
}
return false;
}
function getRandomLatLng(map) {
var bounds = map.getBounds(),
southWest = bounds.getSouthWest(),
northEast = bounds.getNorthEast(),
lngSpan = northEast.lng - southWest.lng,
latSpan = northEast.lat - southWest.lat;
return L.latLng(
southWest.lat + latSpan * Math.random(),
southWest.lng + lngSpan * Math.random());
}
populate();
map.addLayer(markers);
</script>
</body>
</html>
While your Leaflet-related JS code seems ok, you probably have errors popping in your browser console (open your browser Developer Tools).
Looking at your HTML code:
you load twice Leaflet, making L namespace being overridden the 2nd time
you try loading Leaflet.markercluster only after the first Leaflet load, making only the "first" L namespace being augmented with L.markerClusterGroup factory, whereas the 2nd (final) L does not have it
you try loading Leaflet.markercluster assets through an incorrect path
Therefore:
loading Leaflet only once is enough
make sure to load Leaflet.markercluster after the last Leaflet load
fix the path to Leaflet.markercluster assets (remove the "browse" part)

I've built and app using javascript /firebase and would like to have it return the last 5 searches and make each of them clickable

I've built an app that is working fine. The only problem is that I'm trying to have it display the last 5 searches in my HTML div with the id of recentSearches. I would like each of them to be clickable and return the result they previously returned. I refered to my HTML div toward the bottom as: let recentSearchesDiv = $('#recentSearches')
<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase.js"></script>
var config = {
apiKey: "AIzaSyCzaNmYb94HQPR70d6Omy5kP1d0kw5NLkc",
authDomain: "eventtraveler-69f59.firebaseapp.com",
databaseURL: "https://eventtraveler-69f59.firebaseio.com",
projectId: "eventtraveler-69f59",
storageBucket: "eventtraveler-69f59.appspot.com",
messagingSenderId: "73086206077"
};
firebase.initializeApp(config);
var database = firebase.database();
// slider functionality
$(document).ready(function () {
$('.slider').slider({ full_width: true });
});
var $hotelsContainer = $("#hotel-results");
var $eventsContainer = $("#events-results");
// input fields
var $city = $("#location-input");
var $checkInDate = $("#start-date-input");
var $checkOutDate = $("#end-date-input");
var $submit = $("#add-event");
// make global variable so functions can access
var city = "";
var checkin = "";
var checkout = "";
var pleaseWait = "";
// CORS un-blocker for eventful API
jQuery.ajaxPrefilter(function(options) {
if (options.crossDomain && jQuery.support.cors) {
options.url = "https://cors-anywhere.herokuapp.com/" + options.url;
}
});
function getHotels(city) {
// find location code
$.ajax({
url:
"https://apidojo-kayak-v1.p.rapidapi.com/locations/search?where=" + city,
method: "GET",
headers: {
"X-RapidAPI-Host": "apidojo-kayak-v1.p.rapidapi.com",
"X-RapidAPI-Key": "811b0b509bmshf44ab7ab1214e55p19e182jsnc61a98a0c578"
}
}).then(function(response) {
console.log(response);
console.log(response[0].ctid); // MAKE SURE IT'S A CITY
// make sure it's a city (response returns city and airport codes)
$.each(response, function(i, value) {
if (response[i].loctype === "city") {
console.log("this is a city");
console.log(i + ", " + value);
citycode = response[i].ctid;
console.log(citycode);
return false;
}
});
// now that we have the location code, we can use it to find hotels
$.ajax({
url:
"https://apidojo-kayak-v1.p.rapidapi.com/hotels/create-session?rooms=1&citycode=" +
citycode +
"&checkin=" +
checkin +
"&checkout=" +
checkout +
"&adults=1",
method: "GET",
headers: {
"X-RapidAPI-Host": "apidojo-kayak-v1.p.rapidapi.com",
"X-RapidAPI-Key": "811b0b509bmshf44ab7ab1214e55p19e182jsnc61a98a0c578"
}
}).then(function(response) {
console.log("kajak success");
console.log(response);
console.log(response.hotelset);
// reference for hotel list
var hotelListMain = response.hotelset;
var hotelList = response.hotelset;
// only keep 10 results
if (hotelList.length > 10) {
hotelList.length = 10;
}
console.log(hotelList);
// if no results
if (hotelList.length === 0) {
console.log("no results");
var newP = $("<p>").text("No results.");
$hotelsContainer.append(newP);
}
// go through each hotel and show on page
$.each(hotelList, function(i, value) {
console.log("hotel " + i);
// get relevent info
if (response.hotelset[i].brand !== undefined) {
var hotelName = response.hotelset[i].brand;
} else {
var hotelName = response.hotelset[i].name;
}
var hotelAddress = response.hotelset[i].displayaddress;
var hotelRating = response.hotelset[i].ratinglabel;
var hotelStarCount = response.hotelset[i].stars;
var hotelThumbnail =
"https://kayak.com" + response.hotelset[i].thumburl;
// if cheapest provider object is included
console.log("t/f: " + response.hotelset[i].cheapestProvider !== undefined);
if (response.hotelset[i].cheapestProvider !== undefined) {
var cheapestProviderName = response.hotelset[i].cheapestProvider.name;
var bestPrice =
response.hotelset[i].cheapestProvider.displaybaseprice;
var linkToHotel =
"https://kayak.com" + response.hotelset[i].cheapestProvider.url;
} else {
var cheapestProviderName = response.hotelset[i].brand;
var bestPrice = response.hotelset[i].price;
var linkToHotel = "https://kayak.com" + response.hotelset[i].shareURL;
}
//create elements for html
var newTitle = $("<h5>").text(
hotelName + " (via " + cheapestProviderName + ")"
);
var newAddress = $("<p>").text(hotelAddress);
var newPrice = $("<p>").text(bestPrice);
var newRating = $("<p>").text(
hotelRating + ", " + hotelStarCount + " stars"
);
var newImage = $("<img>").attr("src", hotelThumbnail);
var newLink = $("<a>")
.attr("href", linkToHotel)
.text("see hotel");
// img container
var imgContainer = $("<div>")
.addClass("card-image")
.append(newImage);
var content = $("<div>")
.addClass("card-content")
.append(newTitle, newAddress, newPrice, newRating);
var action = $("<div>")
.addClass("card-action")
.append(newLink);
// content container
var allContentContainer = $("<div>")
.addClass("card-stacked")
.append(content, action);
// make parent div for this hotel
var newHotelDiv = $("<div>")
.append(imgContainer, allContentContainer)
.addClass("card horizontal");
// add this hotel's div to the hotel container
$hotelsContainer.append(newHotelDiv);
// remove wait message
pleaseWait.remove();
});
});
});
}
function displayEvent() {
$("#events-results").empty();
var where = $("#location-input")
.val()
.trim();
var start = moment($("#start-date-input").val()).format("YYYYMMDD00");
var end = moment($("#end-date-input").val()).format("YYYYMMDD00");
// search for button name in omdb and show info underneath
var queryURL =
"https://api.eventful.com/json/events/search?" +
"app_key=n69CWBNZRrGZqdMs" +
"&l=" +
where +
"&t=" +
start +
"-" +
end;
console.log(queryURL);
$.ajax({
url: queryURL,
method: "GET"
}).then(function(response) {
var schema = JSON.parse(response);
console.log(schema.events);
console.log(schema.events.event);
// if no results
if (schema.events.event.length === 0) {
console.log("no event results");
var newP = $("<p>").text("No results.");
$eventsContainer.append(newP);
}
for (var i = 0; i < schema.events.event.length; i++) {
total = parseFloat(i) + 1;
//create elements for html
var eventTitle = $("<h5>").text(schema.events.event[i].title);
var eventAddress = $("<p>").text(
schema.events.event[i].venue_address +
", " +
schema.events.event[i].city_name +
", " +
schema.events.event[i].postal_code
);
var eventLink = $("<a>")
.attr("href", schema.events.event[i].url)
.text("see event");
// img container
if (schema.events.event[i].image !== null) {
var eventimage = schema.events.event[i].image.medium.url;
if (eventimage.includes("http")) {
var neweventImage = $("<div>")
.addClass("card-image")
.append("<img src='" + eventimage + "'/>");
} else {
var neweventImage = $("<div>")
.addClass("card-image")
.append("<img src='https:" + eventimage + "'/>");
}
}
// start time
var begins = schema.events.event[i].start_time;
var days = schema.events.event[i].all_day;
if (begins.includes("00:00:00")) {
var date = begins.slice(0, 10);
var startTime = $("<p>").text("Starts on " + date + ". Happening for " + days + " days");
} else {
var date = begins.slice(0, 16);
var startTime = $("<p>").text(begins);
}
//build container
var eventContent = $("<div>")
.addClass("card-content")
.append(eventTitle, eventAddress, startTime);
var eventAction = $("<div>")
.addClass("card-action")
.append(eventLink);
// content container
var eventContentContainer = $("<div>")
.addClass("card-stacked")
.append(eventContent, eventAction);
// make parent div for this event
var newEventDiv = $("<div>")
.append(neweventImage, eventContentContainer)
.addClass("card horizontal");
// add this event's div to the event container
$("#events-results").append(newEventDiv);
}
})
}
$submit.on("click", function (event) {
event.preventDefault();
// clear out current results
$hotelsContainer.empty();
$eventsContainer.empty();
// save their inputted data
city = $city.val().trim();
checkin = $checkInDate.val();
checkout = $checkOutDate.val();
var citycode = "";
// if user filled out all fields
if (city !== "" && checkin !== "" && checkout !== "") {
// show message that results are being generated - so user knows button did submit
if ($(".please-wait").length === 0) {
console.log("results are generating....please wait");
pleaseWait = $("<p>").text("Searching for results...").addClass("please-wait");
$(document.body).append(pleaseWait);
pleaseWait.insertAfter($submit);
}
// get hotel results and display them
//getHotels();
// get event results and display them
//displayEvent();
// construct object literal for firebase
let travelEvent = {
city,
checkin,
checkout
};
// add event to firebase
database.ref().push(travelEvent)
database.ref().limitToLast(5).on("value", snapshot => {
let keys = Object.keys(snapshot.val())
let recentSearchesDiv = $('#recentSearches');
recentSearchesDiv.empty();
for(let i = 0; i < keys.length; i++) {
let val = snapshot.val()[keys[i]]
let city = val.city
let checkin = val.checkin
let checkout = val.checkout
let search = $(`<div><span>City: ${city} </span><span>Check-in: ${checkin} </span><span>Check-out: ${checkout}</span></div>`);
search.addClass('recentSearch')
search.on('click', function(){
})
recentSearchesDiv.append(search)
}
});
// clear inputs
$city.val("");
$checkInDate.val("");
$checkOutDate.val("");
} else {
// show error message
if ($(".required-error").length === 0) {
var required = $("<p>").text("* All fields are required").addClass("required-error");
$("#event-form").prepend(required);
}
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>EventTraveler</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel="stylesheet" type="text/css "href="assets/css/style.css">
</head>
<body>
<div class="container">
<nav>
<!--Creating NavBar-->
<div class="nav-wrapper">
<img src="assets/images/logo2.png" class="brand-logo">
</div>
</nav>
<!-- Slider Images -->
<div id="slider-container">
<div class="slider">
<ul class="slides">
<li>
<img src="assets/images/beach.png">
</li>
<li>
<img src="assets/images/concert.png">
</li>
<li>
<img src="assets/images/mountain.png">
</li>
<li>
<img src="assets/images/attraction.png">
</li>
</ul>
</div>
</div>
<div>
<h1>Search for hotels and events</h1>
<!-- Create the form -->
<form id="event-form">
<label for="location-input" id="location">Enter city and state</label>
<input type="text" id="location-input" /><br />
<label for="start-date-input" id="checkin">Check In</label>
<input type="date" id="start-date-input" /><br />
<label for="end-date-input" id="checkout">Check Out</label>
<input type="date" id="end-date-input" /><br />
<!-- Button triggers new event to be added -->
<input id="add-event" class="btn btn-info" type="submit" value="Search" />
</form>
</div>
<div>
<h4>Recent Searches</h4>
<div id="recentSearches">
</div>
</div>
<div class="banner-div">
<img src="assets/images/banner.jpg" id= "banner">
</div>
<!-- create cards right -->
<div class="row">
<div class="col s6" id = "right">
<h3 class="header">Hotels</h3>
<div id = "hotel-results">
<div class="card horizontal">
<div class="card-image">
<img src="assets/images/hotels.jpg">
</div>
<div class="card-stacked">
<div class="card-content">
<p>Use the search form above to see results</p>
</div>
</div>
</div>
</div>
</div>
<!-- create cards right -->
<div class="col s6" id = "Left">
<h3 class="header">Events</h3>
<div id="events-results">
<div class="card horizontal">
<div class="card-image">
<img src="assets/images/events.jpg">
</div>
<div class="card-stacked">
<div class="card-content">
<p>Use the search form above to see results</p>
</div>
</div>
</div>
</div>
</div>
</div>
<footer class=“page-footer”>
<div class=“footer-copyright”>
<div class=“container”>
© 2019 Los Cinco
</div>
</div>
</footer>
</div>
<script src="https://code.jquery.com/jquery-3.4.0.min.js"integrity="sha256-BJeo0qm959uMBGb65z40ejJYGSgR7REI4+CW1fNKwOg="crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/2.12.0/moment.min.js"></script>
<script src="assets/javascript/main.js"></script>
</body>
</html>
If I understand it correctly, your only problem is that there are more then 5 Elements displayed? You can set a limit on the results returned.
https://dinosaur-facts.firebaseio.com/yourJson.json?
orderBy="price"&limitToLast=5;
As you can see, you can also sort it by a Property, e.g. Price and then query only a set number of items. It is also possible to specify if it should be ordered ASC oder DESC.

Google Maps iFrame not loading when using javascript variables on "src"

I have an html file with javascript used to get the exif data out of an image, more specifically GPS latitude and longitude.
That data is the converted to a format readable by a Google Maps iFrame to then show where that photo was taken...
The problem I'm having at the moment is on the use of JavaScript variables that contain the values of the latitude and longitude on the "src" of the iFrame.
If I use the specific values on the source, the iFrame loads correctly on that specific location... but if I replace them with the variables that DO have the same exact values, nothing loads... the iFrame stays blank.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>EXIF</title>
<style>
img{
width: 500px;
max-height: auto;
}
</style>
</head>
<body>
<img src="https://c1.staticflickr.com/5/4867/30883801817_bf122bc498_o.jpg" id="img1" />
<iframe id="mapa_google" src="" width="640" height="480"></iframe>
<h1>Latitude Exif</h1>
<p id="local_lat"></p>
<h1>Longitude Exif</h1>
<p id="local_lon"></p>
<h1>Latitude Final</h1>
<p id="local_lat_final"></p>
<h1>Longitude Final</h1>
<p id="local_lon_final"></p>
<script src="exif.js"></script>
<script>
var toDecimal = function (number) {
var d = Math.floor(number[0]);
var m = Math.floor(number[1]);
var s = ((number[1]%1)*60);
var dms= d+(m/60)+(s/3600);
return dms
};
window.onload=getExif;
function getExif() {
img1 = document.getElementById("img1");
EXIF.getData(img1, function() {
latitude = EXIF.getTag(this, "GPSLatitude");
longitude = EXIF.getTag(this, "GPSLongitude");
local_lat = document.getElementById("local_lat");
local_lon = document.getElementById("local_lon");
local_lat.innerHTML = `${latitude}`;
local_lon.innerHTML = `${longitude}`;
latitude_final = toDecimal(latitude);
local_lat_final = document.getElementById("local_lat_final");
local_lat_final.innerHTML = `${latitude_final}`;
longitude_final = toDecimal(longitude);
local_lon_final = document.getElementById("local_lon_final");
local_lon_final.innerHTML = `${longitude_final}`;
});
}
getExif();
document.getElementById("mapa_google").src = "https://www.google.com/maps/embed/v1/place?key=AIzaSyDQSbRMCIv1gDsT2qRsY8HvLyZP11hte_Y&q="+latitude_final+"+"+longitude_final;
/* IF I USE THE CODE BELOW WITH THE SPECIFIC LATITUDE AND LONGITUDE, THE iFrame works perfectly but id I use the one above, with the variables that contain those same values, nothing loads on that iFrame... it stays blank*/
document.getElementById("mapa_google").src = "https://www.google.com/maps/embed/v1/place?key=AIzaSyDQSbRMCIv1gDsT2qRsY8HvLyZP11hte_Y&q=41.38448666666667+2.1066883333333335";
</script>
</body>
</html>
The getExif() function is asynchronous. You need to use the results of the asynchronous load of the <img> inside the callback function, once the image has loaded.
function getExif() {
img1 = document.getElementById("img1");
EXIF.getData(img1, function() {
latitude = EXIF.getTag(this, "GPSLatitude");
longitude = EXIF.getTag(this, "GPSLongitude");
local_lat = document.getElementById("local_lat");
local_lon = document.getElementById("local_lon");
local_lat.innerHTML = `${latitude}`;
local_lon.innerHTML = `${longitude}`;
latitude_final = toDecimal(latitude);
local_lat_final = document.getElementById("local_lat_final");
local_lat_final.innerHTML = `${latitude_final}`;
longitude_final = toDecimal(longitude);
local_lon_final = document.getElementById("local_lon_final");
local_lon_final.innerHTML = `${longitude_final}`;
document.getElementById("mapa_google").src = "https://www.google.com/maps/embed/v1/place?key=AIzaSyDQSbRMCIv1gDsT2qRsY8HvLyZP11hte_Y&q=" + latitude_final + "+" + longitude_final;
});
proof of concept fiddle
code snippet:
img {
width: 500px;
max-height: auto;
}
<script src="https://cdn.jsdelivr.net/gh/exif-js/exif-js#2.3.0/exif.js"></script>
<img src="https://c1.staticflickr.com/5/4867/30883801817_bf122bc498_o.jpg" id="img1" onload="getExif();" />
<iframe id="mapa_google" src="" width="640" height="480"></iframe>
<h1>Latitude Exif</h1>
<p id="local_lat"></p>
<h1>Longitude Exif</h1>
<p id="local_lon"></p>
<h1>Latitude Final</h1>
<p id="local_lat_final"></p>
<h1>Longitude Final</h1>
<p id="local_lon_final"></p>
<script>
var toDecimal = function(number) {
var d = Math.floor(number[0]);
var m = Math.floor(number[1]);
var s = ((number[1] % 1) * 60);
var dms = d + (m / 60) + (s / 3600);
return dms
};
// window.onload = getExif;
function getExif() {
img1 = document.getElementById("img1");
EXIF.getData(img1, function() {
latitude = EXIF.getTag(this, "GPSLatitude");
longitude = EXIF.getTag(this, "GPSLongitude");
local_lat = document.getElementById("local_lat");
local_lon = document.getElementById("local_lon");
local_lat.innerHTML = `${latitude}`;
local_lon.innerHTML = `${longitude}`;
latitude_final = toDecimal(latitude);
local_lat_final = document.getElementById("local_lat_final");
local_lat_final.innerHTML = `${latitude_final}`;
longitude_final = toDecimal(longitude);
local_lon_final = document.getElementById("local_lon_final");
local_lon_final.innerHTML = `${longitude_final}`;
document.getElementById("mapa_google").src = "https://www.google.com/maps/embed/v1/place?key=AIzaSyDQSbRMCIv1gDsT2qRsY8HvLyZP11hte_Y&q=" + latitude_final + "+" + longitude_final;
});
}
// getExif();
</script>

javascript adding new buildings

I'm not sure how to add a new building by array. I'm a beginner javascript person.
I added saving/loading among other things to the back end but the client side is giving me issues for some reason.
I think it has something to do with me not under standing arrays correctly but if you could point me in the right direction i would love to learn.
I want to add a second building called
loadbuilding("taco stand")
Here is the code:
var Timer = window.setInterval(function() {
Tick()
}, 1000);
var buildings = [];
//The object declaration for game saves
function GameSave() {
this.money = 0;
this.buildings = [];
for (var i = 0; i < buildings.length; i++) {
this.buildings[i] = 0;
}
}
//The object declaration for buildings
function Building() {
this.Name = "Lemonade Stand";
this.Cost = 10;
this.PerSec = 1;
}
//The function to initialise all buildings
function InitBuildings() {
LoadBuilding("Lemonade Stand", 10, 1);
LoadBuilding("Taco Stand", 100, 1);
}
//The function to automatically load a building into the buildings array
function LoadBuilding(name, cost, persec) {
var cur = buildings.length;
buildings[cur] = new Building();
buildings[cur].Name = name;
buildings[cur].Cost = cost;
buildings[cur].PerSec = persec;
}
//The function used to gather money
function GatherMoney() {
game.money++; //++ tells javascript to add 1 to the variable
//Display the player's current money
document.getElementById("money").innerHTML = game.money;
}
//The function that gets run every second
function Tick() {
for (var i = 0; i < buildings.length; i++) {
game.money += game.buildings[i] * buildings[i].PerSec;
}
document.getElementById("money").innerHTML = game.money;
}
//The function to buy a lemonade stand
function Build(id) {
if (game.money >= buildings[id].Cost) { //Check if the player has enough money, then subtract it and add a new building if they do
game.money -= buildings[id].Cost;
game.buildings[id] = game.buildings[id] + 1;
document.getElementById("money").innerHTML = game.money;
document.getElementById("Building1Qty").innerHTML = game.buildings[id];
}
}
//Run this code once the page has loaded fully
window.onload = function() {
InitBuildings();
window.game = new GameSave();
};
<!--Pleae refer to Lesson 9.txt for a full description on this lesson -->
<html>
<head>
<title>Basic Incremental Game</title>
<link rel="stylesheet" type="text/css" href="css/Incremental.css">
<script src="js/Incremental.js"></script>
</head>
<body>
<div id="page">
<div id="header">
<div id="game-title">
Basic Incremental Game
</div>
</div>
<div id="content">
<div id="stats" class="block">
<div class="label">Money:</div>
<div id="money" class="label">0</div>
</div>
<div id="clickables" class="block">
<input type="button" value="Click Me!" onclick="GatherMoney();">
</div>
<div id="buildings" class="block">
<div id="Building1">
<input type="button" value="Lemonade Stand" onclick="Build(0);">
<div>
<div class="label">Cost:</div>
<div id="Building1Cost" class="label">10</div>
</div>
<div>
<div class="label">Per Sec:</div>
<div id="Building1PerSec" class="label">1</div>
</div>
<div>
<div class="label">Quantity:</div>
<div id="Building1Qty" class="label">0</div>
</div>
</div>
<div id="Building2">
<input type="button" value="Taco Stand" onclick="Build(1);">
<div>
<div class="label">Cost:</div>
<div id="Building2Cost" class="label">10</div>
</div>
<div>
<div class="label">Per Sec:</div>
<div id="Building2PerSec" class="label">1</div>
</div>
<div>
<div class="label">Quantity:</div>
<div id="Building2Qty" class="label">0</div>
</div>
</div>
</div>
<div id="upgrades" class="block">
This is where our upgrades will go!
</div>
</div>
</body>
EDIT:
i tried changing the but tit didnt work
buildings[]
to
buildings["Lemonade Stand", "Taco Stand"]
How about,
LoadBuilding("myBuilding", 12, 1);
Because you have this factory function,
function LoadBuilding(name, cost, persec) {
var cur = buildings.length;
buildings[cur] = new Building();
buildings[cur].Name = name;
buildings[cur].Cost = cost;
buildings[cur].PerSec = persec;
}
You could build an array of Building objects then iterate through them using a while loop.
See JSFIDDLE, or attached code.
Let me know if that helps.
class Building {
constructor(name, cost, persec) {
this.name = name;
this.cost = cost;
this.persec = persec;
}
}
var buildings = [];
buildings.push(new Building('Building One', '$10', '1'));
buildings.push(new Building('Building Two', '$20', '0.5'));
buildings.push(new Building('Building Three', '$25', '2'));
var count = 0;
while(count < buildings.length) {
document.getElementById('stores').innerHTML += '<p>' + buildings[count].name + '<br />' + buildings[count].cost + '<br />' + buildings[count].persec + '</p>';
count++;
}
<div id="stores">
</div>

Why do I get TypeError: response.getDataTable(...) is null when while using Google Fusion Tables Layers?

I am trying to use the Autocomplete text search example on https://developers.google.com/fusiontables/docs/samples/autocomplete however when I replace the table id I get a TypeError. I can see my markers however when I try to search nothing happens.
Here are my files:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="UTF-8">
<title>Map Search Engine</title>
<link href="style.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/base/jquery-ui.css" type="text/css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script type="text/javascript">
google.load('visualization', '1');
function initialize() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(51.545032, -0.05642),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var tableId = '1lhqB6x3JubMAvA9zPf3ByzzvgWFamb24xDmH0_op'
var locationColumn = 'Address';
var layer = new google.maps.FusionTablesLayer({
query: {
select: locationColumn,
from: tableId
},
map: map
});
initAutoComplete(tableId);
// Update layer when user clicks find.
google.maps.event.addDomListener(document.getElementById('find'), 'click',
function() {
var Library = document.getElementById('Library').value;
if (Library) {
Library = Library.replace(/'/g, '\\\'');
var where = "'Library Names' CONTAINS IGNORING CASE '" +
Library + "'";
layer.setOptions({
query: {
select: locationColumn,
from: tableId,
where: where
}
});
}
});
}
function initAutoComplete(tableId) {
// Retrieve the unique Library names using GROUP BY workaround.
var queryText = encodeURIComponent(
"SELECT 'Library Name', COUNT() " +
'FROM ' + tableId + " GROUP BY 'Library Name'");
var query = new google.visualization.Query(
'http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
query.send(function(response) {
var numRows = response.getDataTable().getNumberOfRows();
// Create the list of results for display of autocomplete.
var results = [];
for (var i = 0; i < numRows; i++) {
results.push(response.getDataTable().getValue(i, 0));
}
// Use the results to create the autocomplete options.
$('#Library').autocomplete({
source: results,
minLength: 2
});
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
<div>
<input type="text" id="Library">
<input type="button" value="Find" id="find">
<small>HINT: Try typing "Dalston"</small>
</div>
</body>
</html>
CSS
html {
height: 100%;
margin: 0px;
padding: 0px
}
body {
font-family: Arial, sans-serif;
font-size: 12px;
}
#map-canvas {
height: 500px;
width: 600px;
}
#visualization {
height: 400px;
width: 500px;
}
Please Help!!
The reason I was getting a TypeError was because in my query I put Library Name rather than Library Names as it is in the FusionTable.
function initAutoComplete(tableId) {
// Retrieve the unique Library names using GROUP BY workaround.
var queryText = encodeURIComponent(
"SELECT 'Library Name', COUNT() " +
'FROM ' + tableId + " GROUP BY '*Library Name*'");
var query = new google.visualization.Query(
'http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
Thank you to Dr. Molle for helping me pinpoint the issue.

Categories