I'm working on having multiple timers run in Javascript with the user data and time remaining pulled from a PHP + MySQL instance
Currently I have the following PHP Code:
<?php
$now = strtotime("now");
$allArrested = $conn->query("SELECT `user_id` FROM `user_jail` WHERE `jail_stop` > '$now'") or die(mysqli_error($conn));
if($allArrested->num_rows > 0){
while($arrested = $allArrested->fetch_assoc()){
foreach($arrested as $jailTime){
$checkTime = $conn->query("SELECT `jail_stop` FROM `user_jail` WHERE `user_id` = '$jailTime'") or die(mysqli_error($conn));
while($letsTime = $checkTime->fetch_assoc()){
$x = $letsTime['jail_stop'];
$letGo = $x - $now;
foreach($arrested as $convict){
echo "<div>".usernameById($convict)." for <span class=\"time\">".$letGo."</span></div>";
}
}
}
}
}
?>
And the following javascript:
<script>
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (--timer < 0) {
timer = 0;
display.textContent = "";
}
}, 1000);
}
window.onload = function () {
var fiveMinutes = <?php echo $letGo; ?>,
display = document.querySelector('.time');
startTimer(fiveMinutes, display);
};
</script>
For testing purposes I have 4 different usernames. Currently only the first one is counting down.
The other 3 users counters remain on 90sec (variable $letGo).
Is anyone able to help me with this?
Related
I am new to this. I have a Qaultrics survey consisting of different blocks; each block with its own timer. What I want to achieve is the following; if participants complete the first block before the given time, the timer on that block will be cleared as they move to the next block where a new timer would start. In the following block, a new timer needs to start.
Any assistance would be greatly appreciated.
Qualtrics.SurveyEngine.addOnload(function()
{
var headerCont = document.createElement("div");
headerCont.className = "header-cont";
headerCont.id = "header_container";
var header = document.createElement("div");
header.className = "header"
header.id = "header_1";
var timer = document.createElement("div");
timer.className = "timer";
timer.id = "timer_1";
timer.innerHTML = "Time Remaining: <span id='time'>01:00</span>";
headerCont.appendChild(header);
header.appendChild(timer);
document.body.insertBefore(headerCont, document.body.firstChild);
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
var myTimer = setInterval(function() {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
var text = ('innerText' in display)? 'innerText' : 'textContent';
display[text] = minutes + ":" + seconds;
if (--timer < 0) {
clearInterval(myTimer);
timeOver();
}
}, 1000);
}
var timerSeconds = 60,
display = document.querySelector('#time');
startTimer(timerSeconds, display);
var timeOver = function() {
document.getElementById("timer_1").innerHTML = "";}
});
Qualtrics.SurveyEngine.addOnUnload(function()
{
clearInterval(myTimer);
clearInterval(timer);
clearInterval(timer_1);
document.getElementById("timer_1").innerHTML = "";
});
Here is what I did;
On the first question I used the following code
```Qualtrics.SurveyEngine.addOnload(function()
{
var headerCont = document.createElement("div");
headerCont.className = "header-cont";
headerCont.id = "header_container";
var header = document.createElement("div");
header.className = "header"
header.id = "header_1";
var timer = document.createElement("div");
timer.className = "timer";
timer.id = "timer_1";
timer.innerHTML = "Time Remaining: <span id='time'>02:10</span>";
headerCont.appendChild(header);
header.appendChild(timer);
document.body.insertBefore(headerCont, document.body.firstChild);
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
var myTimer = setInterval(function() {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
var text = ('innerText' in display)? 'innerText' : 'textContent';
display[text] = minutes + ":" + seconds;
if (--timer < 0) {
clearInterval(myTimer);
timeOver();
}
}, 1000);
}
var timerSeconds = 130,
display = document.querySelector('#time');
startTimer(timerSeconds, display);
var timeOver = function() {
document.getElementById("timer_1").innerHTML = "";}
});```
Then in the last question in the block, I used the following code
{
Qualtrics.SurveyEngine.addOnPageSubmit(function() {
Qualtrics.SurveyEngine.setEmbeddedData('timeRemaining',timer);
clearInterval(myTimer); // fairly certain this isn't doing anything
});
});
Qualtrics.SurveyEngine.addOnReady(function()
{
/*Place your JavaScript here to run when the page is fully displayed*/
});
Qualtrics.SurveyEngine.addOnUnload(function() {
document.getElementById("header_container").remove();
});```
i am a situation here, i have a mysql table called attendance and there is a column named "break" in mysql TIME format 00:00:00 now i need a way to update the time according to user id upon when user clicks start and stop it when clicks stop.
found this bit of code here now can someone guide me through to achieve my goal?
my sql query is
$stmt = $db->prepare("SELECT MAX(attn_id) AS id FROM attendance WHERE member_id = '".$_SESSION['member_id']."'");
$stmt->execute();
$row = $stmt->fetch();
timervalue = $row['break'];
$stmt = $db->prepare("UPDATE attendance SET break = '".timervalue."' WHERE attn_id= '".$row['id']."'");
$stmt->execute();
by default the value in break is stored as 00:00:00
how can i impliment the below code to make it update my database? also get rid of the milliseconds i only need h:m:s
<script type='text/javascript'>
$(function() {
// Some global variables
var startTime = 0,
elapsed = 0,
timerId = 0,
$timer = $("#timer");
function formatTime(time) {
var hrs = Math.floor(time / 60 / 60 / 1000),
min = Math.floor((time - hrs*60*60*1000) / 60 / 1000),
sec = Math.floor((time - hrs*60*60*1000 - min*60*1000) / 1000);
hrs = hrs < 10 ? "0" + hrs : hrs;
min = min < 10 ? "0" + min : min;
sec = sec < 10 ? "0" + sec : sec;
return hrs + ":" + min + ":" + sec;
}
function elapsedTimeFrom(time) {
return formatTime(time - startTime + elapsed);
}
function showElapsed() {
$timer.text(elapsedTimeFrom(Date.now()));
}
function startTimer() {
// React only if timer is stopped
startTime = startTime || Date.now();
timerId = timerId || setInterval(showElapsed, 1000);
}
function pauseTimer() {
// React only if timer is running
if (timerId) {
clearInterval(timerId);
elapsed += Date.now() - startTime;
startTime = 0;
timerId = 0;
}
}
function resetTimer() {
clearInterval(timerId);
$timer.text("01:00:00");
startTime = 0;
elapsed = 0;
timerId = 0;
}
function editTimer() {
pauseTimer();
$timer.prop("contenteditable", true);
$timer.css("border", "1px solid red");
}
function setElapsed() {
var time = $timer.text(),
arr = time.split(":");
$timer.prop("contenteditable", false);
$timer.css("border", "1px solid black");
elapsed = parseInt(arr[0]*60*60, 10);
elapsed += parseInt(arr[1]*60, 10);
elapsed += parseInt(arr[2], 10);
elapsed *= 1000;
}
function sendTime() {
pauseTimer();
// Set hidden input value before send
$("[name='time']").val(formatTime(elapsed));
}
$("[name='start']").click(startTimer);
$timer.dblclick(editTimer);
$timer.blur(setElapsed);
$("form").submit(sendTime);
});
</script>
<h1><div id="timer">00:00:00</span></div>
<form action="" method="post">
<input type="button" name="start" value="Start">
<input type="submit" name="action" value="Submit">
<input type="hidden" name="time" value="00:00:00">
</form>
Really appreciate whole hearty for helping me ot and giving your valuable time and input.
Thanks
Here's a 'proof-of-concept'...
<?php
/*
-- TABLE CREATION STATEMENTS
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table (t TIME NOT NULL DEFAULT 0);
INSERT INTO my_table VALUES ('00:01:50');
*/
require('path/to/connection/stateme.nts');
//If something was posted, update the table. Otherwise, skip this step...
if(sizeof($_POST) != 0){
$x=$_POST['tts'];
$query = "UPDATE my_table SET t = SEC_TO_TIME(?) LIMIT 1";
$stmt = $pdo->prepare($query);
$stmt->execute([$x]);
}
//Grab the stored value from the database...
$query = "
select t
, time_to_sec(t) tts
, LPAD(HOUR(t),2,0) h
, LPAD(MINUTE(t),2,0) i
, LPAD(SECOND(t),2,0) s
from my_table
limit 1
";
//Format the data for ease of use...
if ($data = $pdo->query($query)->fetch()) {
$t = $data['t'];
$tts = $data['tts'];
$h = $data['h'];
$i = $data['i'];
$s = $data['s'];
} else {
$t = 0;
$tts = 0;
$h = '00';
$i = '00';
$s = '00';
}
?>
//Make a simple form, with one, hidden input...
<form id="myForm" method="post">
<input name="tts" type= "hidden" id="tts" value="tts">
<span id="hour"><?php echo $h; ?></span>:
<span id="min"><?php echo $i; ?></span>:
<span id="sec"><?php echo $s; ?></span>
<input id="startButton" type="button" value="Start/Resume">
<input id="pauseButton" type="button" value="Pause">
<button id="submit">Save</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- The timer/stopwatch thingy-->
<script>
var Clock = {
totalSeconds: <?php echo $tts ?>,
start: function () {
if (!this.interval) {
var self = this;
function pad(val) { return val > 9 ? val : "0" + val; }
this.interval = setInterval(function () {
self.totalSeconds += 1;
$("#hour").text(pad(Math.floor(self.totalSeconds / 3600 % 60)));
$("#min").text(pad(Math.floor(self.totalSeconds / 60 % 60)));
$("#sec").text(pad(parseInt(self.totalSeconds % 60)));
<!-- Also provide data in seconds, for ease of use -->
<!-- Note, this is 'val', not 'text' -->
$("#tts").val(pad(parseInt(self.totalSeconds)));
}, 1000);
}
},
pause: function () {
clearInterval(this.interval);
delete this.interval;
},
resume: function () {
this.start();
}
};
$('#startButton').click(function () { Clock.start(); });
$('#pauseButton').click(function () { Clock.pause(); });
</script>
In this function, I have implemented a timer which is working fine in the given html input box without onclick function 'start_test'. but i want to start this inner function on button click which is not working. PLease help me to find the mistake.
function start_test() {
var hms = "01:30:00";
var a = hms.split(':'); // split it at the colons
// minutes are worth 60 seconds. Hours are worth 60 minutes.
var seconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]);
if( seconds > 0 ){
function secondPassed() {
var minutes = Math.round((seconds - 30)/60),
remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = " " +minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
//form1 is your form name
document.form_quiz.submit();
} else {
seconds--;
}
}
var countdownTimer = setInterval('secondPassed()', 1000);
}
}
<div class="col-md-4" style="text-align: right;">
<button class="btn btn-primary" id="start_test" onclick="start_test();" >Start Test</button>
<input type="hidden" value="<?php echo date('M d Y');?>" id="c_month">
<h2><time id="countdown">01:30:00</time> </h2>
</div>
in setInterval(timePassed, 1000) this is 1s or MORE
=> 1000mms is just an indication, the time elapsed depend of the proccessor usage
PROOF:
const one_Sec = 1000
, one_Min = one_Sec * 60
, one_Hour = one_Min * 60
, biDigits = t => t>9?t:`0${t}`
, c_pseudo = document.getElementById('countdownP')
, c_real = document.getElementById('countdownR')
, btTest = document.getElementById('bt-test')
;
btTest.onclick=()=>
{
btTest.disabled = true
let [t_h,t_m,t_s] = '01:30:00'.split(':').map(v=>+v)
, timeEnd = new Date().getTime() + (t_h * one_Hour) + (t_m * one_Min) + (t_s * one_Sec)
, timerRef = setInterval(timePassed, 1000) // 1s or MORE !
;
function timePassed()
{
if (--t_s <0) { t_s = 59; --t_m}
if (t_m <0) { t_m = 59; --t_h }
c_pseudo.textContent = `${biDigits(t_h)}:${biDigits(t_m)}:${biDigits(t_s)}`
let tim = timeEnd - (new Date().getTime())
let tr_h = Math.floor(tim / one_Hour)
let tr_m = Math.floor((tim % one_Hour) / one_Min )
let tr_s = Math.floor((tim % one_Min ) / one_Sec )
c_real.textContent = `${biDigits(tr_h)}:${biDigits(tr_m)}:${biDigits(tr_s)}`
if ( !t_h && !t_m && !t_s)
{
btTest.disabled = false
clearInterval(timerRef)
}
}
}
<button id="bt-test" >Start Test</button>
<h2> pseudo count down <span id="countdownP">01:30:00</span> </h2>
<h2> real count down <span id="countdownR">01:30:00</span> </h2>
This statement is declaring a function countdownTimer, not executing it.
var countdownTimer = setInterval('secondPassed()', 1000);
Try replacing with:
setInterval(() => secondPassed(), 1000);
This should actually execute setInterval
I'm working on a quiz app that need to store the duration from the countdown timer. I tried many solutions but still can't find the right way to do it! What I need exactly is when the submit button is clicked a function will stop the countdown and capture the timer, then send it to another PHP page with POST method or whatever.
Thanks in advance.
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.text("00 : " + minutes + " : " + seconds);
if (timer < 10) {
audio.play();
}
if (--timer < 0) {
window.location.href = "test.php";
}
}, 1000);
}
jQuery(function ($) {
var examtime = 60 * 1,
display = $('#time');
startTimer(examtime, display);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<form action="test.php" method="POST">
<div><span id="time">00 : 01 : 00</span></div>
</form>
</body>
Problem fixed! I had to add a function that pass the value to an input. In addition, disabled inputs don't get submitted, so you have change them to a hidden input. Also, Added this line: $("form").attr("action"); to submit form after taking the value.
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.text("00 : " + minutes + " : " + seconds);
if (--timer < 0) {
window.location.href = "test.php";
}
}, 1000);
}
jQuery(function ($) {
var examtime = 60 * 1,
display = $('#timer');
startTimer(examtime, display);
});
$(document).ready(function(){
$("#submitButton").click(function(){
var theValueToUse = jQuery('#timer').text();
jQuery('#theValue').val(theValueToUse);
$("form").attr("action");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<form id="theForm" action="test.php" method="POST">
<div><span id="timer">00 : 01 : 00</span></div>
<!-- make it hidden -->
<input id="theValue" name="theValue" value="" type="text">
<input id="submitButton" type="submit" value="submit">
</form>
</body>
First, timer is a variable inside a function, JS has function scope, so you can't reach it. If you declare the variable outside the function, timer will be accessed from everywhere, it will have global scope. Its not a good practice to pollute the global scope, but this will work if this is a simple JS. After that , use JQuery ajax to send that that data to the PHP, timer will be available, delete that form.
I am trying to create a countdown and I want to be able to cancel the interval not only when reach 0 but with clicking of a button as well.How can I modify my function to be able to cancel the interval from anywhere in the controller.
function countDown(total) {
total = total * 60;
var interval = $interval(function () {
var minutes = Math.floor(total / 60);
var seconds = total - minutes * 60;
if (minutes < 1)
{
minutes = '0:';
}
else
{
minutes = minutes + ':';
}
if (seconds < 10)
{
seconds = '0' + seconds;
}
self.remainingTime = "Remaining time: " + minutes + seconds;
total--;
if(minutes === '0:' && seconds === '00')
{
$interval.cancel(interval);
}
}, 1000);
}
As suggested by other users, you should make interval global in the controller. Then on the other functions you want to cancel the interval you can call it safely.
Take a look at the below sample:
angular.module('app', [])
.controller('ctrl', function($interval) {
var self = this;
var interval;
self.wizard = {
startInterval: startInterval,
cancelInterval: cancelInterval
};
startInterval();
return self.wizard;
function startInterval() {
countDown(24);
}
function cancelInterval() {
$interval.cancel(interval);
}
function countDown(total) {
cancelInterval();
total = total * 60;
interval = $interval(function() {
var minutes = Math.floor(total / 60);
var seconds = total - minutes * 60;
if (minutes < 1) {
minutes = '0:';
} else {
minutes = minutes + ':';
}
if (seconds < 10) {
seconds = '0' + seconds;
}
self.wizard.remainingTime = "Remaining time: " + minutes + seconds;
total--;
if (minutes === '0:' && seconds === '00') {
$interval.cancel(interval);
}
}, 1000);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<span ng-app="app" ng-controller="ctrl as ctrl">
<span ng-bind="ctrl.remainingTime"> </span>
<br/>
Cancel Interval
<br/>
Start Interval
</span>
I created an example using self instead of $scope like you are in your snippet above. As others mentioned moving the interval var to the global scope fixes this. I also added a stop and start function to test the issue you mentioned in the example above.
UPDATED - I added some code to the stop interval to reset the interval to undefined. I found an example of this usage on Angular's site so it might be worth a try to see if it fixes your other issue.
var app = angular.module('app', []);
app.controller('BaseController', function($interval) {
var self = this;
var interval;
function countDown(total) {
total = total * 60;
interval = $interval(function() {
var minutes = Math.floor(total / 60);
var seconds = total - minutes * 60;
if (minutes < 1) {
minutes = '0:';
} else {
minutes = minutes + ':';
}
if (seconds < 10) {
seconds = '0' + seconds;
}
self.remainingTime = "Remaining time: " + minutes + seconds;
total--;
if (minutes === '0:' && seconds === '00') {
$interval.cancel(interval);
}
}, 1000);
}
self.stopInterval = function(){
if (angular.isDefined(interval)) {
$interval.cancel(interval);
interval = undefined;
}
}
self.startInterval = function(){
countDown(10);
}
});
Then in the html I added a button to start and stop the interval like so:
<body ng-app="app">
<div ng-controller="BaseController as baseCtrl">
{{ baseCtrl.remainingTime }}
<div>
<button ng-click="baseCtrl.startInterval()">Start Countdown</button>
<button ng-click="baseCtrl.stopInterval()">Stop Countdown</button>
</div>
</div>
</body>
You can view the codepen example here