How to make countdown instaed of count up - javascript

I have this code that displays the timer for the exam. Which made by the admin side. the timer is counting the time in count up but i want to make it display in countdown. Unfortunately i could not figure out how to make it display in countdown.
if someone can help me i will be appreciated.
ajax.php
if(isset($_POST['subId']) && isset($_POST['userId'])){
$subId = $_POST['subId'];
$id = $_POST['userId'];
require_once('../admin/inc/db.php');
$subQuery = "SELECT * FROM subject WHERE id = '$subId' AND exam = 'on' ";
$subRun = mysqli_query($con, $subQuery);
if(mysqli_num_rows($subRun) > 0){
$subRow = mysqli_fetch_array($subRun);
$time = $subRow['time'];
$query = "SELECT * FROM timer WHERE user = '$id' AND subject = '$subId' ";
$run = mysqli_query($con, $query);
if(mysqli_num_rows($run) == 0){
$insert = "INSERT INTO timer(user, subject, spent) VALUES('$id', '$subId', 1)";
$insertRun = mysqli_query($con, $insert);
} else{
$row = mysqli_fetch_array($run);
$spent = $row['spent'];
if($spent < $time){
$count = $spent + 1;
$update = "UPDATE timer SET spent = '$count' WHERE user = '$id' AND subject = '$subId' ";
$updateRun = mysqli_query($con, $update);
echo $count;
} else{
echo "Time out!";
}
}
} else{
echo "Time out!";
}
timer.js
$(document).ready(function(){
var subId = $('#subId').val();
var userId = $('#userId').val();
var myVar = setInterval(myTimer, 1000);
function myTimer(){
$.ajax({
type: 'POST',
url: 'inc/ajax.php',
data: { subId: subId, userId: userId },
success: function(res) {
if(res == 'Time out!'){
clearInterval(myVar);
$('#timer').html('Time over!');
$('#exampleModal').modal({
backdrop: 'static',
keyboard: false
});
} else{
var time = res;
if(time < 60){
$('#timer').html('0:' + time);
} else if(time == 60){
$('#timer').html('1:00');
} else{
var min = Math.floor(time/60);
var sec = time % 60;
if(min < 10 && sec < 10){
$('#timer').html(min + ':' + '0' + sec);
} else if(min >= 10 && sec < 10){
$('#timer').html(min + ':' + '0' + sec);
} else{
$('#timer').html(min + ':' + sec);
}
}
}
},
error: function(jqXHR, textStatus, errorThrown){
if(jqXHR){
$('#timer').html('<span class="animated flash infinite">Exam Paused!</span>');
}
}
});
}
});

To make the timer countdown instead of counting up, you need to change the way the time variable is calculated in the success function of the AJAX request. Instead of subtracting the current time from the start time, you need to subtract the start time from the maximum time and display the remaining time.
Here's an updated version of the code that should count down:
$(document).ready(function(){
var subId = $('#subId').val();
var userId = $('#userId').val();
var totalTime = 60; // or whatever maximum time you want to set
var remainingTime = totalTime;
var myVar = setInterval(myTimer, 1000);
function myTimer(){
$.ajax({
type: 'POST',
url: 'inc/ajax.php',
data: { subId: subId, userId: userId },
success: function(res) {
if(res == 'Time out!'){
clearInterval(myVar);
$('#timer').html('Time over!');
$('#exampleModal').modal({
backdrop: 'static',
keyboard: false
});
} else{
remainingTime = totalTime - res; // calculate remaining time
if(remainingTime < 0){
remainingTime = 0; // prevent negative values
}
var min = Math.floor(remainingTime/60);
var sec = remainingTime % 60;
var timeStr = min + ':' + (sec < 10 ? '0' : '') + sec; // format time string
$('#timer').html(timeStr); // display remaining time
}
},
error: function(jqXHR, textStatus, errorThrown){
if(jqXHR){
$('#timer').html('<span class="animated flash infinite">Exam Paused!</span>');
}
}
});
}
});
Note that this code assumes that the maximum time is known and fixed, and that the >res variable returned by the AJAX request represents the time elapsed since the >start of the exam. You may need to adjust the code if these assumptions don't hold >for your use case.

Related

undefined from arrValue.start_date

I am trying to get from my database the start_date and end_date, however, I am getting "undefined" in console from arrValue.start_date or arrValue.(x) regardless of input.
unavailabletimes = [];
is_conflict = false
$.ajax({
url: '<%= preload_parking_path(#parking) %>',
dataTyp: 'json',
success: function(data) {
$.each(data, function(arrID, arrValue){
unavailabletimes.push([moment(moment.utc(arrValue.start_date).format('YYYY-MM-DD HH:mm')), moment(moment.utc(arrValue.end_date).format('YYYY-MM-DD HH:mm'))] );
console.log(arrValue.start_date);
})
var prestart_date = $('#reservation_start_date').datetimepicker('viewDate');
var start_date = moment(moment(prestart_date).format('YYYY-MM-DD HH:mm'));
var preend_date = $('#reservation_end_date').datetimepicker('viewDate');
var end_date = moment(moment(preend_date).format('YYYY-MM-DD HH:mm'));
if(end_date.diff(start_date, 'minutes') < 60){
var duration = 60;
}else{
if((end_date.diff(start_date, 'minutes') % 60) == 0){
var duration = end_date.diff(start_date, 'minutes');
}else{
var duration = ((end_date.diff(start_date, 'minutes') - (end_date.diff(start_date, 'minutes') % 60)) + 60);
}
}
unavailabletimes.forEach((unavailabletime)=> {
// unavailabletime = [moment, moment]
// check with start time and end time
if (start_date <= unavailabletime[0] && end_date >= unavailabletime[1]) {
is_conflict = true
}
});
if(is_conflict) {
$('#message').text("Cannot overlap existing bookings!");
$('#preview').hide();
$('#btn_book').attr('disabled', true);
} else {
var total = duration/60 * <%= #parking.price %>;
$('#message').text("");
$('#preview').show();
$('#btn_book').attr('disabled', false);
$('#reservation_hours').text(duration/60);
$('#reservation_total').text(total);
}
}
});
arrValue on itself works and it returns the database entries but adding the .(x) i.e start_date or end_date.
This is my console for arrValue
What could be the cause of this? What I am trying to do is setup a booking system that does not allow overlapped booking down to the hour. I am trying to retrieve the time interval between start_date and end_date. Push it into unavailabletimes to find conflict. I am new to coding so I apologize if its a little messy.

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();
}

session destroy after count down timer reach 0

use countdown timer for logout user,if user is inactive for 2hrs..
function Timer(duration, display) {
var timer = duration, hours, minutes, seconds;
setInterval(function () {
hours = parseInt((timer /3600)%24, 10)
minutes = parseInt((timer / 60)%60, 10)
seconds = parseInt(timer % 60, 10);
hours = hours < 10 ? "0" + hours : hours;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.text(hours +":"+minutes + ":" + seconds);
if(hours == 0 && minutes == 0 && seconds == 0){
$.ajax({
url:'../ajax/logoutuser.php',
success: function(data){
console.log('logout');
}
});
}else{
--timer;
}
}, 1000);
}
window.onload = function () {
var twentyFourHours = 1 * 1 * 3;
var display = $('#time');
Timer(twentyFourHours, display);
};
and since i cant call session destroy on jquery function i use ajax to make request..
<?php
require_once '../config/database.php';
require_once '../includes/dboperations/user.php';
$database = new Database();
$conn = $database->getConnection();
$db = new User($conn);
$user = json_decode($_SESSION["user"]);
$db->offlineStatus($user->user_id);
session_destroy();
echo "<script>window.location.href = '../index.php'</script>";
?>
but what happens is, it doesnt call the session destroy function after making request. it runs the console.log inside success function..
is there a way to log out user if inactive for 2hrs
You can achieve by php way. Something like
$expiry = 1800 ;//session expiry required after 30 mins
if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
session_unset();
session_destroy();
}
$_SESSION['LAST'] = time();
Instead of echo script from php file out it in success function of ajax code
success: function(data){
console.log('logout');
window.location.href = '../index.php';
}

Ajax still executing even an error found

Good day programmers! I'am trying to submit a form then validate it using jquery with 2 ajax events. I am using ajax(timeconflict.php) for validating if there is conflict with the user's time input. but even tho it returns an error, the other ajax event is still executing(reserveroom.php). sorry for my grammar, here's my code
$('#submitreserve').click(function(){
var error=false;
var inputtimeerror = false;
var conflict = false;
var message="";
var to="";
var from="";
var fromH="";
var fromM="";
var toH="";
var toM="";
var now = new Date();
if($("#datetimepicker").val()=="" || $("#trtitle").val()=="" || $("#from").val()=="" || $("#to").val()=="")
{
error = true;
message ="Please Fill all required Fields!";
}
if($("#from").val()!="" && $("#to").val()!="")
{
from = $("#from").val(); // start time
to = $("#to").val(); // end time
fromH = from.substr(0,2); // get hour from start time
fromM = from.substr(3,2); // get mins from start time
toH = to.substr(0,2); // get hour from end time
toM = to.substr(3,2); // get mins from end time
var timeerror = false;
var inputDate = $("#datetimepicker").val(); // date
inputFrom = new Date(inputDate+" "+from); // time and start date
inputTo = new Date(inputDate+" "+to); // time and end date
if(fromH > toH)
{
timeerror=true;
}
if(fromH == toH && fromM >= toM)
{
timeerror=true;
}
if(to == from)
{
timeerror=true;
}
if(inputFrom <= now || inputTo <= now)
{
inputtimeerror = true;
}
if(error == false && inputtimeerror == false)
{
$.ajax({
type:'post',
url: 'timeconflict.php',
data: { startTime : from,
endTime : to,
inputDate : inputDate,
room : target },
dataType: 'json',
success : function(e)
{
if (e.length == 0)
{
console.log("No value returned");
}
else
{
console.log(e[0]);
console.log("Conflict time schedule!");
conflict = true;
error=true;
alert("Conflict");
return false;
}
}
});
}
if(inputtimeerror)
{
error=true;
message = "Reservation time must be higher than time today!";
}
if(conflict)
{
error = true;
message = "Conflict Time Schedule!";
}
if(timeerror)
{
message = "Invalid End Time!";
error=true;
}
}
if(error==true)
{
$("#error").text(message);
return false;
}
if(error==false)
{
$.ajax({
type:'post',
url: 'reserveroom.php',
data: { trtitle : $("#trtitle").val(),
from : $("#from").val(),
to : $("#to").val(),
datetimepicker : $("#datetimepicker").val(),
ninjaday : $("#ninjaday").val(),
ninjaroom : $("#ninjaroom").val() },
dataType: 'json'
});
}
});
//timeconflict.php
<?php
include ('../conn.php');
// header("Content-Type: application/json");
$start_time = $_POST['startTime'];
$end_time = $_POST['endTime'];
$res_date = $_POST['inputDate'];
$res_room = $_POST['room'];
$sql = "SELECT * from tdc_reservation where ( ((`reserve_start` BETWEEN '".$start_time."' and '".$end_time."')";
$sql.= " or (`reserve_end` BETWEEN '".$start_time."' and '".$end_time."' )) or";
$sql.= " (('".$start_time."' BETWEEN `reserve_start` and `reserve_end`) or ";
$sql.= " ('".$end_time."' BETWEEN `reserve_start` and `reserve_end`)) or ";
$sql.= " ((`reserve_start` = '".$start_time."' ) or (`reserve_end`='".$start_time."' ))";
$sql.= " or ((`reserve_start` = '".$end_time."') or (`reserve_end` = '".$end_time."')) )";
$sql.= " and reserve_date='".$res_date."' and reserve_room = '".$res_room."' LIMIT 1 ";
$result = mysql_query($sql,$con);
$stack = array();
while($row = mysql_fetch_array($result))
{
$stack[] = $row;
}
$json = json_encode($stack);
mysql_close();
echo $json;
?>
I really hope someone would help me, this error already ate 2 days of my life :(
Modified your code, hope this will work
$('#submitreserve').click(function(){
var message="";
var to="";
var from="";
var fromH="";
var fromM="";
var toH="";
var toM="";
var now = new Date();
if($("#datetimepicker").val()=="" || $("#trtitle").val()=="" || $("#from").val()=="" || $("#to").val()=="")
{
message ="Please Fill all required Fields!";
}else{
from = $("#from").val(); // start time
to = $("#to").val(); // end time
fromH = from.substr(0,2); // get hour from start time
fromM = from.substr(3,2); // get mins from start time
toH = to.substr(0,2); // get hour from end time
toM = to.substr(3,2); // get mins from end time
var inputDate = $("#datetimepicker").val(); // date
inputFrom = new Date(inputDate+" "+from); // time and start date
inputTo = new Date(inputDate+" "+to); // time and end date
if(fromH > toH || (fromH == toH && fromM >= toM) || to == from)
{
message = "Invalid End Time!";
}
else if(inputFrom <= now || inputTo <= now)
{
message = "Reservation time must be higher than time today!";
}else{
$.ajax({
type:'post',
url: 'timeconflict.php',
data: { startTime : from,
endTime : to,
inputDate : inputDate,
room : target },
dataType: 'json',
success : function(e)
{
if (e.length == 0)
{
console.log("No value returned");
reserveRoom();
}
else
{
console.log(e[0]);
console.log("Conflict time schedule!");
alert("Conflict");
return false;
}
}
});
}
}
alert(message);
});
function reserveRoom(){
$.ajax({
type:'post',
url: 'reserveroom.php',
data: { trtitle : $("#trtitle").val(),
from : $("#from").val(),
to : $("#to").val(),
datetimepicker : $("#datetimepicker").val(),
ninjaday : $("#ninjaday").val(),
ninjaroom : $("#ninjaroom").val() },
dataType: 'json'
});
}

Count down timer not working with AJAX

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;

Categories

Resources