Count down timer not working with AJAX - javascript

I am trying to make a counter with JS. So far I've managed to pull that off, however I now encounter a problem. While using AJAX to retreive the time to count down I can't make it work. It's weird because it works on my original file but not with a php file called by AJAX.
This works fine :
https://jsfiddle.net/6kvp25vv/
I have no idea what the problem is. This is the HTML page :
<button onclick="upgrade('meat_max')" id="up_meat_max">+</button>
When I click on the button, it runs the function inside this js file which creates a GET request on upgrade.php :
function upgrade(building) {
var file = 'upgrade.php?building=' + building;
ajax(file, function(response) {
document.getElementById('construction').innerHTML += response;
})
}
function ajax(file, fn) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
fn(xmlhttp.responseText);
}
};
xmlhttp.open('GET', file, true);
xmlhttp.send();
}
And this is the code from upgrade.php (variables sent to this file with AJAX are not used for the purpose of testing the code) :
<div class="time">Time: <span id="timer">?</span></div>
var hour = 2;
var minute = 46;
var second = 45;
// function to make a counter
function clockIt() {
function clockO(digit) {
if(digit<10) {
return '0';
} else {
return '';
}
}
document.getElementById('timer').textContent = hour + ':' + clockO(minute) + minute + ':' + clockO(second) + second;
if(second>0) {
second -= 1;
} else if(minute>0) {
minute -= 1;
second += 59;
} else if(hour>0) {
hour -= 1;
minute += 59;
}
}
// runs the function every seconds
clockIt();
setInterval(function (){clockIt()}, 1000);

innerHTML does not execute ajax loaded scripts, what I would do in your case is to return a JSON encoded string with the variables that you need and have a function on your main script (the one thats already loaded) with this provided script, that way you already have the function ready and only pass parameters with the ajax response.
You can decode a json string with:
obj = JSON.parse(jsonString);
For example:
Ajax JSON response string:
{"time": {"hour":2, "minute":46, "second": 45}, "html": "<div class=\"time\">Time: <span id=\"timer\"></span></div>"}
Modified upgrade function:
function upgrade(building) {
var file = 'upgrade.php?building=' + building;
ajax(file, function(response) {
obj = JSON.parse(response);
time = obj.time;
document.getElementById('construction').innerHTML += obj.html;
startCountdown(time.hour, time.minute, time.second);
})
}
New function
function startCountdown(hour, minute, second) {
// function to make a counter
function clockIt() {
function clockO(digit) {
if(digit<10) {
return '0';
} else {
return '';
}
}
document.getElementById('timer').textContent = hour + ':' + clockO(minute) + minute + ':' + clockO(second) + second;
if(second>0) {
second -= 1;
} else if(minute>0) {
minute -= 1;
second += 59;
} else if(hour>0) {
hour -= 1;
minute += 59;
}
}
// runs the function every seconds
clockIt();
setInterval(function (){clockIt()}, 1000);
}

My problem was with the method for the countdown timer. When you specify an interval of 1000 milliseconds, you can't count on it being 1000 milliseconds. It's actually as soon as the timer loop gets to it after 1000 milliseconds have passed. Over a period of time, there are going to be some delays. What you want to do, if you want accurate timing, is to store the initial settings and then measure the time from when the countdown was started to the current time. See the code below which bases the timer on the internal clock rather than the interval counter. Once you have the number of seconds, you can easily it convert it to hours, minutes, and seconds by dividing by 3600 for the hours and using division and modulo arithmetic for the minute and second.
See https://www.sitepoint.com/creating-accurate-timers-in-javascript/
How to create an accurate timer in javascript?
<!DOCTYPE html />
<html>
<head>
<meta encoding="UTF-8" />
<title>Testing XMLHttpRequest</title>
<script>
var request;
var button1;
var display1;
var display2;
var display3;
var start;
var counter;
function second() {
display2.value = display2.value + "\r\nreadyState=" + request.readyState + " status=" + request.status + "\r\n";;
if (request.readyState == 4 && request.status == 200) {
display1.value = display1.value + request.responseText + "\r\n";
}
}
function first() {
display2.value = display2.value + "\r\n" +
"Starting page \r\n";
request = new XMLHttpRequest();
request.onreadystatechange = second;
var file = "http://localhost:80/";
request.open('GET', file, true);
request.send();
setInterval(timed, 1000);
}
function starter() {
display1 = document.getElementById("display1");
display2 = document.getElementById("display2");
display3 = document.getElementById("display3");
button1 = document.getElementById("button1");
button1.onclick = first;
start = new Date();
counter = 60;
}
function timed() {
var duration = (start.getTime() - new Date().getTime()) / 1000.0;
display3.value = (duration + counter).toFixed(0);
}
window.onload = starter;
</script>
</head>
<body>
<form>
<p>
<input type="button" id="button1" value="Start" />Timer:
<input type="text" readonly="readonly" id="display3" />
</p>
<p>Status:
<textarea rows="5" cols="30" id="display2"></textarea>
</p>
<p>Response:
<textarea rows="60" cols="80" id="display1"></textarea>
</p>
</form>
</body>
</html>

Found a way to compensate the delays, using the original version :
function upgrade(building) {
var file = 'upgrade.php?building=' + building;
ajax(file, function(response) {
var obj = JSON.parse(response);
var time = obj.time;
document.getElementById('construction').innerHTML += obj.html;
run_clockIt(time.hour, time.minute, time.second);
})
}
// general AJAX launcher
function ajax(file, fn) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
fn(xmlhttp.responseText);
}
};
xmlhttp.open('GET', file, true);
xmlhttp.send();
}
// count down timer with adjustments to compensate delay
function clockIt(hour, minute, second, finished, nbOfLoop) {
// every 5 seconds, run a delay correction
if(nbOfLoop%5 == 0) {
var actualTimeLeft = adjustClock(finished);
minute = actualTimeLeft[0];
second = actualTimeLeft[1];
}
nbOfLoop += 1;
// add a string "0" if necessary
function clockO(digit) {
if(digit<10) {
return '0';
} else {
return '';
}
}
document.getElementById('timer').textContent = hour + ':' + clockO(minute) + minute + ':' + clockO(second) + second;
// update displayed timer
if(second>0) {
second -= 1;
} else if(minute>0) {
minute -= 1;
second += 59;
} else if(hour>0) {
hour -= 1;
minute += 59;
}
// waits 1 sec before launching the next one
setTimeout(function() {
clockIt(hour, minute, second, finished, nbOfLoop);
}, 1000);
}
// runs the function for the first time
function run_clockIt(hour, minute, second) {
var finished = new Date();
finished.setUTCHours(finished.getUTCHours() + hour);
finished.setUTCMinutes(finished.getUTCMinutes() + minute);
finished.setUTCSeconds(finished.getUTCSeconds() + second);
clockIt(hour, minute, second, finished, 1);
}
function adjustClock(finished) {
var now = new Date();
var diff = new Date(Math.abs(now - finished));
return [diff.getUTCMinutes(), diff.getUTCSeconds()];
}
This way, the count down timer is smooth, no lagging and most of all you can define the interval on which the adjust function will run and correct the timer.
This is the php file, preparing the JSON object (thanks #Miguel) :
<?php
header('Content-Type: application/json');
// retreive variables from AJAX call
$building = $_REQUEST['building'];
// processing variable with database...
// prepare JSON object
$jsonData = '
{
"time":{"hour":2, "minute":46, "second": 45},
"html": "<div class=\"time\">Time: <span id=\"timer\"></span></div>"
}
';
echo $jsonData;

Related

How to Execute Javascript inside html automatically and use ajax to send the variables into php?

I have found a java script that can measure user download speed and it is very close to the real speed and here is the code.
//JUST AN EXAMPLE, PLEASE USE YOUR OWN PICTURE!
var imageAddr = "http://www.kenrockwell.com/contax/images/g2/examples/31120037-5mb.jpg";
var downloadSize = 4995374; //bytes
function ShowProgressMessage(msg) {
if (console) {
if (typeof msg == "string") {
console.log(msg);
} else {
for (var i = 0; i < msg.length; i++) {
console.log(msg[i]);
}
}
}
var oProgress = document.getElementById("progress");
if (oProgress) {
var actualHTML = (typeof msg == "string") ? msg : msg.join("<br />");
oProgress.innerHTML = actualHTML;
}
}
function InitiateSpeedDetection() {
ShowProgressMessage("Loading the image, please wait...");
window.setTimeout(MeasureConnectionSpeed, 1);
};
if (window.addEventListener) {
window.addEventListener('load', InitiateSpeedDetection, false);
} else if (window.attachEvent) {
window.attachEvent('onload', InitiateSpeedDetection);
}
function MeasureConnectionSpeed() {
var startTime, endTime;
var download = new Image();
download.onload = function () {
endTime = (new Date()).getTime();
showResults();
}
download.onerror = function (err, msg) {
ShowProgressMessage("Invalid image, or error downloading");
}
startTime = (new Date()).getTime();
var cacheBuster = "?nnn=" + startTime;
download.src = imageAddr + cacheBuster;
function showResults() {
var duration = (endTime - startTime) / 1000;
var bitsLoaded = downloadSize * 8;
var speedBps = (bitsLoaded / duration).toFixed(2);
var speedKbps = (speedBps / 1024).toFixed(2);
var speedMbps = (speedKbps / 1024).toFixed(2);
ShowProgressMessage([
"Your connection speed is:",
speedBps + " bps",
speedKbps + " kbps",
speedMbps + " Mbps"
]);
}
}
I have really no experience with java script at all, First, I want to edit this code to execute without showing any messages at all and then I want it to run automatically in an empty html and using ajax to redirect page to a ( url + speedMbps javascript variable ).
For example, if the url is http://url.com/get.php?speed= and the speedMbps = 23 then I want the redirect url to look like that http://url.com/get.php?speed=23
Thank you very much for your help

Execute PHP script if a JavaScript condition is true

I am running a javascript timer that can be activated by a start button and whenever the count is more than 30 minutes I want it to run an email script so that the email can be send to the intended recipient with the user having to actually send the email manually.Here is the php email code`
<?php
$to = "sa01#gmail.com";
$subject = "Vehicle Monitoring system ";
$message = "<b>Vehicle not logged out</b>";
$header = "From:vehicle001#gmail.com \r\n";
$header .= "Cc:sa001#gmail.com \r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-type: text/html\r\n";
$retval = mail ($to,$subject,$message,$header);
if( $retval == true ) {
echo "Message sent successfully...";
}else {
echo "Message could not be sent...";
}
?>`
Here is my javascript code`
var status =0;
var time = 0;
function start() {
status = 1;
document.getElementById("startBtn").disabled = true;
timer();
}
function stop(numberPlate) {
status = 0;
var time = document.getElementById('timerLabel').innerHTML;
var car_no = numberPlate;
var stx = {no : time};
console.log(stx);
window.localStorage.setItem(car_no, time);
}
function reset() {
status = 0;
time = 0;
document.getElementById("startBtn").disabled = false;
document.getElementById("timerLabel").innerHTML = "00:00:00";
}
function timer() {
if (status == 1) {
setTimeout(function() {
time++;
var min = Math.floor(time/100/60);
var sec = Math.floor(time/100);
var mSec = time % 100;
if(min < 10) {
min = "0" + min;
}
if (sec >= 60) {
sec = sec % 60;
}
if (sec < 10) {
sec = "0" + sec;
}
document.getElementById("timerLabel").innerHTML = min + ":" + sec + ":"
+ mSec;
timer();
}, 10);
}
}
function output() {
document.getElementById('timerResult').innerHTML =
document.getElementById('timerLabel').innerHTML;
if(timer>=1){
var xhttp = new XMLHttpRequest();
var result;
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log("Success");
result = xhttp.responseText;
}
};
xhttp.open("GET", "sendmail.php", true);
xhttp.send();
}
`
This is how the table looks like.How do I do that?
You could use XMLHttpRequest() to have the PHP file be requested.
In this example, file.php is accessed if condition is true. The result is stored in the result variable.
if(condition){
var xhttp = new XMLHttpRequest();
var result;
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log("Success");
result = xhttp.responseText;
}
};
xhttp.open("GET", "file.php", true);
xhttp.send();
}

Using JavaScript only, how can I query a google sheet and assign the value of a single cell as a JavaScript variable?

I am wanting to drive a web page using data from a few google sheets.
I’ve figure out how to query my sheet, but the data displays as a datatable and that’s not what I’m looking for. I’d like to be able to take the query cell value and insert it into HTML code. I will also use the value in another query in order to retrieve other information from a different google sheet.
I have two live pages:
http://www.bandstand.ca/widget
This page is a starter skeleton version of my project. I have “Day 5” statically coded and formatted for now but want to replace it with query data as per:
http://www.bandstand.ca/widget/sas.html
I had tried using getValue(0,0) but must not have had something set right. I am totally new to using queries and have not been able to figure out if JavaScript can do anything with the content of the response. I tried hiding the div element that the query fills and just parsing content of the data table, but again, couldn’t figure out a workable solution. I’ve tried searching through the api documentation but I’m not finding anything that looks right either. Surely there’s a way to extract the data and use it within other html. I don’t particularly care if the code is clean (as I’m sure you can tell, I’ve hacked apart other peoples’ code to get the sas.html file down to where it’s at.) I just want something that works.
I’m a teacher and thought this would be an easy little project to build an in-class announcement page that I could have displayed all the time in my room and have it cycle through my schedule of classes via my easily updated google sheets. So far, not so easy! If anyone can help tweak my code to get what I’m asking, I’d sure be grateful!
You can try something like this:
function GetCurrentDate() {
var currentTime = new Date();
var month = currentTime.getMonth() + 2;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var currentDate = "'" + year + "-" + month + "-" + day + "'";
return currentDate;
}
function CreateUrl(key, gql) {
var gq = 'SELECT '+ gql;
var encodedgg = encodeURIComponent(gq);
var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg;
return url;
}
function Request(url, responseFunction) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")"));
var responseJSON = JSON.parse(response);
responseFunction(responseJSON);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML = value;
})
}
var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ';
var currentDate = GetCurrentDate();
var gql = "C WHERE A = DATE " + currentDate;
var url = CreateUrl(gsKey, gql);
var previewElement = document.getElementById('preview');
preview(previewElement, url);
<html>
<head>
<title>Student Announcement System</title>
</head>
<body>
<div id="preview">initial value</div>
</body>
</html>
Here is link to jsbin snippet. (Inline stackoverflow snippet might not work because of CORS and Access-Control-Allow-Origin.)
EDIT after Greg Duguid's comment:
There are three problems with your code:
Your scripts are not working at all. Try to run following snippet:
<script>
document.write("Text 1")
</script>
<script language = "text/javascript">
document.write("Text 2")
</script>
<script type = "text/javascript">
document.write("Text 3")
</script>
When you run it you should get something like Text 1 Text 3 and that is because <script language = "text/javascript"> is wrong and won't work, language parameter is deprecated and you should use type instead. Also in HTML5 you can omit type parameter so it is best to use syntax like this <script>document.write("Text")</script>.
There is syntax error in function preview: last bracket ( should be ).
// OLD CODE
/*
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
//elm.innerHTML = value;
DayNumber = value;
}
( // ERROR IS IN THIS LINE
}
*/
// NEW CODE
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
//elm.innerHTML = value;
DayNumber = value;
}
) // error WAS in this line
}
Code in line:
<font size="+6" color="#FFFF00">Day <script>document.write(DayNumber);</script></font>
When you call function document.write(DayNumber) variable DayNumber is equal to "" because function preview is still not executed at that moment. Reason for this is that execution of function preview takes time. (Because you are retrieving data from sheet document, usually when you retrieve data from server or something similar that takes time.) Execution of code in javascript is asynchronous which means that javscript doesn't wait for function to finish with execution and goes on. Look at this example:
function getData() {
// some function that takes time to get data from server, ducument, or something else
return data;
}
var data = getData();
document.write(data);
In first line function getData() is called, but data will be set to undefined because program will not wait for function getData() to return its value. So function document.write(data) will not preview anything.
(Also it is not good practice to use script tag inside another tag. So you should avoid putting script tag inside font tag like this: <font size="+6" color="#FFFF00">Day <script>document.write(DayNumber);</script></font>.)
Solution for this problem is that you add id to you font tag and than change text in font tag in javascript inside function preview:
function GetCurrentDate() {
var currentTime = new Date();
var month = currentTime.getMonth();
var day = currentTime.getDate() + 1;
var year = currentTime.getFullYear();
var currentDate = "'" + year + "-" + month + "-" + day + "'";
return currentDate;
}
function CreateUrl(key, gql) {
var gq = 'SELECT '+ gql;
var encodedgg = encodeURIComponent(gq);
var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg;
return url;
}
function Request(url, responseFunction) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")"));
var responseJSON = JSON.parse(response);
responseFunction(responseJSON);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML += " " + value;
}
)
}
var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ';
var currentDate = GetCurrentDate();
var gql = "C WHERE A = DATE " + currentDate;
var url = CreateUrl(gsKey, gql);
var previewElement = document.getElementById('preview');
preview(previewElement, url);
<html>
<title>Student Announcement System</title>
<body>
<font size="+6" color="#FFFF00" id="preview">Day</font>
</body>
</html>
This last code should be solution to your problem. Also here is link to jsbin snippet (because stackoverflow snippet might not work when you run it).
EDIT after second Greg Duguid's comment:
Sorry it took little longer to answer. Problem is in line:
var previewElement = document.getElementById('preview');
When this line is executed previewElement is not found and it is set to undefined. This is because javascript code in script tag (<script>...</script>) is before body tag (<body>...</body>) so code is executed before elements in body are defined. So when your page is run, first javascript code is executed and then element <font id="preview">Day</font> is defined. There is simple solution for this: You need to put your script tag at the end of body like this:
<html>
<head>
<style type="text/css">
<!--
body {
background-color: #003c66;
}
-->
</style>
<title>Student Announcement System</title>
</head>
<body>
<font size="+6" color="#FFFF00" id="preview">Day</font>
<script>
function GetCurrentDate() {
var currentTime = new Date();
var month = currentTime.getMonth()+1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var currentDate = "'" + year + "-" + month + "-" + day + "'";
return currentDate;
}
function CreateUrl(key, gql, sheet) {
var gq = 'SELECT '+ gql;
var encodedgg = encodeURIComponent(gq);
var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg + '&gid=' + sheet;
return url;
}
function Request(url, responseFunction) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")"));
var responseJSON = JSON.parse(response);
responseFunction(responseJSON);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML += " " + value;
}
)
}
var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ';
var gsSheet='349215948';
var currentDate = GetCurrentDate();
var gql = "C WHERE A = DATE " + currentDate;
var url = CreateUrl(gsKey, gql, gsSheet);
var previewElement = document.getElementById('preview');
preview(previewElement, url);
</script>
</body>
</html>
And again here is jsbin snippet which should work.
EDIT after this Greg Duguid's comment:
The problem is in your query:
var PERIODgql = "C WHERE A = " + value + " AND B = " + CurrentPeriod;
CurrentPeriod is string so you need to add single quotes around it like this:
var PERIODgql = "C WHERE A = " + value + " AND B = '" + CurrentPeriod + "'";
When it is created, PERIODgql will be something like:
"C WHERE A = 1 AND B = 'P5'"
These queries are similar to SQL queries (which are used to get data form SQL database), you can read more about this here.
Also i noticed your function FindCurrentPeriod:
function FindCurrentPeriod() {
var CurrentPeriod;
var CurrentDate = new Date();
//////////////////////////////
//FOR TESTING VARIOUS TIMES
CurrentDate.setHours(14);
CurrentDate.setMinutes(0);
//////////////////////////////
var CurrentHour = CurrentDate.getHours();
var CurrentMinute = CurrentDate.getMinutes();
if (CurrentHour < 8) {
CurrentPeriod = "Before School";
}
if (CurrentHour == 8) {
if (CurrentMinute < 40) {
CurrentPeriod = "Before School";
} else {
CurrentPeriod = "P1";
}
}
if (CurrentHour == 9) {
if (CurrentMinute < 40) {
CurrentPeriod = "P1";
} else {
if (CurrentMinute < 45) {
CurrentPeriod = "B12";
} else {
CurrentPeriod = "P2";
}
}
}
if (CurrentHour == 10) {
if (CurrentMinute < 37) {
CurrentPeriod = "P2";
} else {
if (CurrentMinute < 47) {
CurrentPeriod = "B23";
} else {
CurrentPeriod = "P3";
}
}
}
if (CurrentHour == 11) {
if (CurrentMinute < 39) {
CurrentPeriod = "P3";
} else {
if (CurrentMinute < 44) {
CurrentPeriod = "B34";
} else {
CurrentPeriod = "P4";
}
}
}
if (CurrentHour == 12) {
if (CurrentMinute < 36) {
CurrentPeriod = "P4";
} else {
CurrentPeriod = "Lunch";
}
}
if (CurrentHour == 13) {
if (CurrentMinute < 13) {
CurrentPeriod = "Lunch";
} else {
CurrentPeriod = "P5";
}
}
if (CurrentHour == 14) {
if (CurrentMinute < 5) {
CurrentPeriod = "P5";
} else {
if (CurrentMinute < 10) {
CurrentPeriod = "B56";
} else {
CurrentPeriod = "P6";
}
}
}
if (CurrentHour == 15) {
if (CurrentMinute < 2) {
CurrentPeriod = "P6";
} else {
CurrentPeriod = "After School";
}
} else {
CurrentPeriod = "After School";
}
return CurrentPeriod;
}
While this is working, it is not really easy to read and there is some repeating conditions so if need to change your code later, that will be harder to do. So I would suggest using a function to help you compare time (in hours and minutes). You can add just short function like this:
function time(hours, minutes) {
return hours*60 + minutes;
}
Now you can compare times 10:50 and 11:25 like this:
if (time(10,50) < time(11,25)) {
//part when you do what you want if condition is ture
}
So you can write your function FindCurrentPeriod like this:
function FindCurrentPeriod() {
var CurrentPeriod;
var CurrentDate = new Date();
//////////////////////////////
//FOR TESTING VARIOUS TIMES
CurrentDate.setHours(14);
CurrentDate.setMinutes(0);
//////////////////////////////
var CurrentHour = CurrentDate.getHours();
var CurrentMinute = CurrentDate.getMinutes();
var cirrentTime = time(CurrentHour, CurrentMinute);
if (cirrentTime < time(8, 40)) {
CurrentPeriod = "Before School";
}
else if (cirrentTime < time(9, 40)) {
CurrentPeriod = "P1";
}
else if (cirrentTime < time(9, 45)) {
CurrentPeriod = "B12";
}
else if (cirrentTime < time(10, 37)) {
CurrentPeriod = "P2";
}
else if (cirrentTime < time(10, 47)) {
CurrentPeriod = "B23";
}
else if (cirrentTime < time(11, 39)) {
CurrentPeriod = "P3";
}
else if (cirrentTime < time(11, 44)) {
CurrentPeriod = "P3";
}
else if (cirrentTime < time(12, 36)) {
CurrentPeriod = "P4";
}
else if (cirrentTime < time(13, 13)) {
CurrentPeriod = "Lunch";
}
else if (cirrentTime < time(14, 5)) {
CurrentPeriod = "P5";
}
else if (cirrentTime < time(14, 10)) {
CurrentPeriod = "B56";
}
else if (cirrentTime < time(15, 2)) {
CurrentPeriod = "P6";
}
else {
CurrentPeriod = "After School";
}
return CurrentPeriod;
}
This is shorter and also easier to read and change if needed.
Here is whole code in stackoverflow snippet (again I'll add jsbin snippet below, because inline stackoverflow snippet might not work because of CORS rules):
function preview2(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML = value;
})
}
function GetCurrentDate() {
var currentTime = new Date();
var month = currentTime.getMonth() + 1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var currentDate = "'" + year + "-" + month + "-" + day + "'";
return currentDate;
}
function CreateUrl(key, gql, sheet) {
var gq = 'SELECT ' + gql;
var encodedgg = encodeURIComponent(gq);
var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg + '&gid=' + sheet;
return url;
}
function time(hours, minutes) {
return hours*60 + minutes;
}
function FindCurrentPeriod() {
var CurrentPeriod;
var CurrentDate = new Date();
//////////////////////////////
//FOR TESTING VARIOUS TIMES
CurrentDate.setHours(14);
CurrentDate.setMinutes(0);
//////////////////////////////
var CurrentHour = CurrentDate.getHours();
var CurrentMinute = CurrentDate.getMinutes();
var cirrentTime = time(CurrentHour, CurrentMinute);
if (cirrentTime < time(8, 40)) {
CurrentPeriod = "Before School";
}
else if (cirrentTime < time(9, 40)) {
CurrentPeriod = "P1";
}
else if (cirrentTime < time(9, 45)) {
CurrentPeriod = "B12";
}
else if (cirrentTime < time(10, 37)) {
CurrentPeriod = "P2";
}
else if (cirrentTime < time(10, 47)) {
CurrentPeriod = "B23";
}
else if (cirrentTime < time(11, 39)) {
CurrentPeriod = "P3";
}
else if (cirrentTime < time(11, 44)) {
CurrentPeriod = "P3";
}
else if (cirrentTime < time(12, 36)) {
CurrentPeriod = "P4";
}
else if (cirrentTime < time(13, 13)) {
CurrentPeriod = "Lunch";
}
else if (cirrentTime < time(14, 5)) {
CurrentPeriod = "P5";
}
else if (cirrentTime < time(14, 10)) {
CurrentPeriod = "B56";
}
else if (cirrentTime < time(15, 2)) {
CurrentPeriod = "P6";
}
else {
CurrentPeriod = "After School";
}
return CurrentPeriod;
}
function preview1(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML += " " + value;
var CurrentPeriod = FindCurrentPeriod();
var PERIODgsSheet = '618896702';
var PERIODgql = "C WHERE A = " + value + " AND B = '" + CurrentPeriod + "'";
var PeriodURL = CreateUrl(gsKey, PERIODgql, PERIODgsSheet);
var periodElement = document.getElementById('period1');
preview2(periodElement, PeriodURL);
})
}
var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ';
var DAYgsSheet = '349215948';
var currentDate = GetCurrentDate();
var DAYgql = "C WHERE A = DATE " + currentDate;
var DayURL = CreateUrl(gsKey, DAYgql, DAYgsSheet);
var previewElement = document.getElementById('preview');
preview1(previewElement, DayURL);
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="refresh" content="600" />
<title>Student Announcement System</title>
<style type="text/css">
<!--
body {
background-color: #003c66;
}
-->
</style>
<!-- CSS Code -->
<style type="text/css" scoped>
.GeneratedMarquee {
font-family:'Arial Black', sans-serif;
font-size:8em;
font-weight:bold;
line-height:2em;
text-align:left;
color:#ffff00;
background-color:#003c66;
padding:40pt;
}
</style>
</head>
<body>
<table width=100%>
<tr>
<td width=240px>
<iframe scrolling="no" frameborder="no" clocktype="html5" style="overflow:hidden;border:0;margin:0;padding:0;width:240px;height:80px;"src="https://www.clocklink.com/html5embed.php?clock=004&timezone=MST&color=white&size=240&Title=&Message=&Target=&From=2018,1,1,0,0,0&Color=white"></iframe>
</td>
<td nowrap>
<center>
<font size="80px" color="#FFFF00" id="preview">DAY </font>
</center>
</td>
<td width=100%>
<a class="weatherwidget-io" href="https://forecast7.com/en/53d54n113d49/edmonton/" data-label_1="EDMONTON" data-font="Helvetica" data-icons="Climacons Animated" data-days="7" data-theme="original" data-basecolor="#003c66" ></a>
<script>
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src='https://weatherwidget.io/js/widget.min.js';fjs.parentNode.insertBefore(js,fjs);}}(document,'script','weatherwidget-io-js');
</script>
</td>
</tr>
</table>
<font color="FFFFFF", size="+6">
<script language=javascript>
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
var today = new Date();
document.write(today.toLocaleDateString("en-US", options)); // Saturday, September 17, 2016
formattedDate = today.toLocaleDateString("en-US", options);
</script>
</font>
<br><font size="80px" color="#FFFF00" id="period1">Class:</font>
<script src="sas.js"></script>
</body>
</html>
Here is jsbin snippet.

passing current timer's timing to the next page

How would i pass my current timer's timing into the next page?
Timer code
var expires = new Date();
expires.setSeconds(expires.getSeconds() + 60); // set timer to 60 seconds
var counter = setInterval(timer, 1);
function timer() {
var timeDiff = expires - new Date();
if (timeDiff <= 0) {
clearInterval(counter);
document.getElementById("timer").innerHTML = "00:00";
return;
}
var seconds = new Date(timeDiff).getSeconds();
var milliSeconds = (new Date(timeDiff).getMilliseconds()/10).toFixed(0);
var seconds = seconds < 10 ? "0" + seconds: seconds;
var milliSeconds = milliSeconds < 10 ? "0" + milliSeconds: milliSeconds;
document.getElementById("timer").innerHTML = seconds + ":" + milliSeconds; // watch for spelling
}
I'm using
<h3 style="color: #ff0000; margin: 0; padding: 0; font-size: 100%;font-weight:normal; font-family: robotolight;"> You have <div id="timer"></div> to complete the game!
in my html.
Is there a way to pass div id='timer'> into the next page?
Thanks.
Reloading the page or loading a new page means reloading javascript since it is runs in the context of the current page. There is good way to pass along javascript variables to a new page; it requires some form of data persistence. Cookies and localStorage are two of the most common ways of persisting data client-side.
Client cookies are written to the browser cache and are transparent in HTTP headers. LocalStorage is a newer mechanism but well supported, allowing up to 5MB of browser storage without passing in headers.
In your use case, instead of storing the timer it would probably make sense to store the timestamp when the timer was started. That way it can be recalculated in the next page from this one static start value.
var timerStart;
var expireDate = new Date();
function displayTimer(){
var now = new Date().getTime();
var timerStart = timerStart || cookieTimer();
val timeDiff = now - timerStart;
document.getElementById("timer").innerHTML = timeDiff.toString();
if(timeDiff > expireDate.getTime()) clearInterval(timerInterval);
}
val timerInterval = setInterval(displayTimer, 1);
// Using cookies
function cookieTimer(){
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1);
if (c.indexOf(name) != -1) return c.substring(name.length,c.length);
}
return "";
}
function setCookie(cname, cvalue, expireDate) {
var d = new Date();
d.setTime(d.getTime() + expireDate.getTime());
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}
var timerCookie = getCookie("timer");
if(timerCookie !== "") return new Date(timerCookie).getTime());
else {
setCookie("timer", timerStart, expireDate);
return new Date().getTime();
}
}
// Using localStorage
function localStorageTimer(){
function setLocalStorageObject(key, obj, expireDate){
obj.expires = expireDate.getTime();
localStorage.setItem(key, JSON.stringify(obj));
}
function getLocalStorageObject(key){
val item = localStorage.getItem(key);
if(item) return JSON.parse(item);
else return {};
}
var timerLocal = getLocalStorageObject("timer");
var now = new Date().getTime();
if(timerLocal && timerLocal.startTime && timerLocal.expires > now) return timerLocal.startTime;
else {
setLocalStorageObject("timer", { startTime: now });
return now;
}
}

Refreshing KML data in Google Maps V3

I have a map that I have ported from V2 to V3 and I am trying to update the code to refresh the KML data at a set time. In this case every 30 secs. It is just suppose to update the data on the map and show the countdown for when the next update happens.
Here is a working version of how it is suppose to work in V2.
V2 EXAMPLE
Here is the relevant code in the V3 script I have updated but it is not working. I am not getting any errors so I am not sure what I am doing wrong. This is working on V2 but I can't get it to work with V3. What am I missing and overlooking?
//This calls genkml.php on every refresh cycle to generate a new kml file
function UpdateKML() {
//document.getElementById('TheDiv').innerHTML = '0';
var xmlhttp=false;
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp=false;
}
}
if (!xmlhttp && window.createRequest) {
try {
xmlhttp = window.createRequest();
} catch (e) {
xmlhttp=false;
}
}
xmlhttp.open("GET", "genkml.php?force=" + force + "&ofd=" + KMLdate + "&nsd=" + NSdate + "&dbg=" + dbg + "&rand="+(new Date()).valueOf(),true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
var resp = xmlhttp.responseText;
//if (resp === undefined) resp = ''; // If we get a bad response, just set resp to nothing
if (dbg == 'y') { // Check if we want debug info
var tmpresp = resp;
if (tmpresp === undefined) tmpresp = ' ';
if (document.getElementById('div1') == null) { // Check if debug div exists, if not add it to end of body
var divTag = document.createElement("div");
divTag.id = "div1";
divTag.innerHTML = 'Response Status: ' + xmlhttp.status + '<br />' + tmpresp;
document.body.appendChild(divTag);
} else { // Otherwise just update the info
document.getElementById('div1').innerHTML = 'Response Status: ' + xmlhttp.status + '<br />' + tmpresp;
}
} else { // Else check if debug div exists and remove it (will take an update to remove
if (document.getElementById('div1') != null) document.body.removeChild(document.getElementById("div1"));
}
if (resp !== undefined) { // Make sure we got data
KMLdate = resp.split("|")[0].split("~")[0];
NSdate = resp.split("|")[0].split("~")[1];
updateHTML(resp); // This calls the updateHTML function if there is info returned
}
}
}
xmlhttp.send(null);
// add back overlays
nyLayer = new google.maps.KmlLayer(null);
nyLayer.setMap(null); // Remove overlays
var nyLayer = new google.maps.KmlLayer(URLToKML + "?rand="+(new Date()).valueOf(),
{
suppressInfoWindows: false,
map: map,
preserveViewport: true,
zIndex: 999
});
// Time overlayed on map - could be in updateHTML() to just show when .kml read last
var time = CurrentTime ("B", "12a", true, TZOffset)
document.getElementById('currenttime').innerHTML = time;
}
function CurrentTime (type, hours, secs, ofs) {
/*
type (char) hours (char) secs (bool) ofs (num)
"U"-UTC "24"=24 hr time true=hh:mm:ss 0=hours from UTC
"B"-User's Browser "12"=12 hr time false=hh:mm
"S"-Web Site "12a"=am/pm
*/
if (type == null){ type = "B"; } // These are the defaults
if (hours == null){ hours = "12a"; }
if (secs == null){ secs = true; }
if (ofs == null){ ofs = 0; }
var currentHour = 0;
var currentMinute = 0;
var currentSecond = 0;
var time = 0;
var currentDate = new Date();
if (type == "U") {
currentHour = currentDate.getUTCHours(); // UTC
} else if (type == "B") {
currentHour = currentDate.getHours(); // Viewer's time
} else {
currentHour = currentDate.getUTCHours() + ofs; // your local time
if(currentHour < 0) { currentHour = currentHour + 24;}
}
currentMinute = currentDate.getMinutes();
currentMinute = (currentMinute < 10 ? "0" : "") + currentMinute;
if (hours == "24") {
if(currentHour == 24) { currentHour = 0 }; // use if wanting 24 hour time
currentHour = (currentHour < 10 ? "0" : "") + currentHour;
} else if (hours == "12") {
if(currentHour == 0) currentHour = 12;
currentHour = (currentHour < 10 ? "0" : "") + currentHour;
} else {
if(currentHour == 0) currentHour = 12; // else no leading zero for am/pm
}
time = currentHour + ":" + currentMinute;
if (secs) {
currentSecond = currentDate.getSeconds();
currentSecond = (currentSecond < 10 ? "0" : "") + currentSecond;
time = time + ":" + currentSecond;
}
if (hours == "12a") {
time = time + " " + (currentHour > 12 ? "PM" : "AM");
}
return time;
}
//This function is only used if you leave the debug checkbox below
// You can remove this function and the checkbox and set the debug
// mode using the dbg=y query parameter
function debug(obj){
if (obj.checked) {
dbg='y';
} else {
dbg='n';
if (document.getElementById('div1') != null) document.body.removeChild(document.getElementById("div1"));
//document.getElementById('TheDiv').innerHTML = '';
}
}
//This function is only used if you leave the Force Update checkbox below
// You can remove this function and the checkbox and set the force
// mode using the force=y query parameter
function forceupdate(obj){
if (obj.checked) {
force='y';
} else {
force='n';
}
}
//This function parses out the query parameter value
function gup( name ){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
Here is a link to the full .js map code for V3 if anyone needs to see it.
V3 NSGAMP CODE
V3 FULL PAGE
EDIT: I think it has to do with this snippet of code that is suppose to remove then add the updated KML data to the map.
This was in V2 which is depreciated now.
// add back overlays
map.removeOverlay(geoXml); //Remove overlays
geoXml = new GGeoXml(URLToKML + "?rand="+(new Date()).valueOf() ); //rand is used to trick google maps into thinking this is a new KML (don't use cache version)
map.addOverlay(geoXml); //Add the new data from the newly generated KML
Code I updated for V3 replacing the above depreciated V2 snippet which was found by searching. Not sure if this is correct but it was all I could find.
// add back overlays
nyLayer = new google.maps.KmlLayer(null);
nyLayer.setMap(null); // Remove overlays
function refresh(layer) {
var nyLayer = new google.maps.KmlLayer(URLToKML + "?rand="+(new Date()).valueOf(),
{
suppressInfoWindows: false,
map: map,
preserveViewport: true,
zIndex: 999
});
}
I got it sorted and working and I knew it was a simple edit but I was having a really difficult time finding a solution. If anyone else this could help this is what I did.
Changed this in the V2 version.
updateHTML(resp); //This calls the updateHTML function if there is info returned
}
}
}
xmlhttp.send(null);
// add back overlays
map.removeOverlay(geoXml); //Remove overlays
geoXml = new GGeoXml(URLToKML + "?rand="+(new Date()).valueOf() ); //rand is used to trick google maps into thinking this is a new KML (don't use cache version)
map.addOverlay(geoXml); //Add the new data from the newly generated KML
To this in the V3 version.
updateHTML(resp); // This calls the updateHTML function if there is info returned
}
//remove layer
window.nyLayer.setMap(null);
//change its url so that we would force the google to refetch data
window.nyLayer.url = URLToKML + "?rand="+(new Date()).valueOf();
//and re-add layer
window.nyLayer.setMap(window.map);
}
}
xmlhttp.send(null);
The map.removeOverlay and map.addOverlay is depreciated in V3 so it took me while to find the replacement.
Or you can simplify it even further and use:
window.nyLayer.url = URLToKML + '&ver=' + Date.now();

Categories

Resources