I have a PHP-script that adds time into a SQL-DB like this:
$howlong = 75; // Amount of seconds
$timetowait=time()+ $howlong; // This inserts into "timetowait" in SQL DB
Then to show my users how long they have to wait, I have this:
$timeleft= $rows['timetowait']; // This is the field in DB from above^
func_time($timeleft); // Function below, which shows the time left
The function above is:
function func_time($until){
$now = time();
$difference = $until - $now;
$seconds = $difference;
$output = "$seconds seconds";
return $output;
}
It works fine, but I want it to be a dynamic countdown. (Automaticly counting down, without refreshing the site) My problem here, is that I am using the "time()", and not pure text (f.ex 21/11/2013 20:00)
Usually this type of "countdown" like thing is handled by Javascript:
On the client side you could do something like this:
function countdown(seconds) {
if(seconds > 0) {
alert(seconds + ' Seconds Left');
setTimeout(function(){
countdown(--seconds);
}, 1000);
}
else {
alert('Time out!');
}
}
Demo: http://jsfiddle.net/qwertynl/fn4MV/
It is better to handle this on client side using javascript.
For example a count down per user could be as follows,
js
function printData(data){
document.getElementById("countdown").innerText=data;
}
var timeInSecs = Date.now()/(1000*60);
var howLong = 75;
var untilTimeInSecs = timeInSecs+howLong;
var countDownInterval = setInterval(function(){
var timeLeft = untilTimeInSecs-timeInSecs;
printData(timeLeft);
untilTimeInSecs--;
if(timeLeft<=0){
clearInterval(countDownInterval);
}
},1000);
html
<div id="countdown"></div>
http://jsfiddle.net/zvsyu/2/
You need javascript, if you have the number of second for the countdown, You only need a setInterval:
More info: http://www.w3schools.com/js/js_timing.asp
Related
I will like to achieve something in a quiz system.
Right about now I have a quiz system that works perfectly well. It closes the quiz after 10:00 min is elapsed.
But what I want now is, for each of the question there should be a timer.
So Question 1 would have 10 secs, Question 2 would also have 10 secs down to Question 20.
So when you fail to answer any question within ten seconds, it automatically takes you to the next question.
Right about now, what happens is that you must click on the next question button before it takes you to the next question, which is what I want to change.
Below is the code that does the timer and submit after 10 min
<script>
//function that keeps the counter going
function timer(secs){
var ele = document.getElementById("countdown");
ele.innerHTML = "Your Time Starts Now";
var mins_rem = parseInt(secs/60);
var secs_rem = secs%60;
if(mins_rem<10 && secs_rem>=10)
ele.innerHTML = " "+"0"+mins_rem+":"+secs_rem;
else if(secs_rem<10 && mins_rem>=10)
ele.innerHTML = " "+mins_rem+":0"+secs_rem;
else if(secs_rem<10 && mins_rem<10)
ele.innerHTML = " "+"0"+mins_rem+":0"+secs_rem;
else
ele.innerHTML = " "+mins_rem+":"+secs_rem;
if(mins_rem=="00" && secs_rem < 1){
quiz_submit();
}
secs--;
//to animate the timer otherwise it'd just stay at the number entered
//calling timer() again after 1 sec
var time_again = setTimeout('timer('+secs+')',1000);
}
</script>
<script>
setTimeout(function() {
$("form").submit();
}, 600000);
</script>
Here is the code that does the onclick to next question
<script type="text/javascript">
$('.cont').addClass('hide');
count=$('.questions').length;
$('#question'+1).removeClass('hide');
$(document).on('click','.next',function(){
last= parseInt($(this).attr('id'));
nex = last+1;
$('#question'+last).addClass('hide');
$('#question'+nex).removeClass('hide');
});
$(document).on('click','.previous',function(){
last = parseInt($(this).attr('id'));
pre = last-1;
$('#question'+last).addClass('hide');
$('#question'+pre).removeClass('hide');
});
setTimeout(function() {
$("form").submit();
}, 120000);
</script>
Please note that I fetch my questions with Php Mysqli
Initialize a timeout into a variable at start. The callback should simulate a click on the next button. Use .click() to simulate. It will execute all click event listeners associated to the button.
You also have to reset the timer when button is clicked (manually or not).
EDIT: After discussing by comments, I guess that you have <button.next> tags for each question in your HTML, with a numeric ID. So I propose you to stock in a variable your current progression.
// Initializes
let currentQuestion = 1;
let question_timer = setTimeout(question_timeout_callback, 10000);
// Function which simulates the click.
function question_timeout_callback() {
// Simulates
$(document).find(`#${currentQuestion}`).click();
}
// your code...
// And in your click event listener:
$(document).on('click','.next', function () {
// Resets timer
clearTimeout(question_timer);
question_timer = setTimeout(question_timeout_callback, 10000);
// Update question tracking
currentQuestion++;
// your code...
});
// Do NOT forget to update .previous buttons with "currentQuestion--"
Now, do not forget to ask yourself how you will handle the possibility to come back to the previous question.
i would suggest different approach.
first, take the time-counting to the backend of your application (so user can't tamper with it).
when user begins quiz, save start time and user identifier into db.
implement timeout (2s interval?) to ask backend, how much time is left.
create simple script which loads remaining time from db (calculates how much time remains for current question) and returns it to the frontend.
php:
<?php
$user = (int) $_GET['user'];
$questionNumber = (int) $_GET['question'];
//connect to the db
//select eg. with PDO
$st = $db->prepare('SELECT start_time FROM quiz_completion WHERE user_id = :user');
$st->bindParam(':user', $user, PDO::PARAM_INT);
$startTimeRow = $sth->execute();
//calculate remaining time
$elapsed = time() - $startTimeRow['start_time'];
$borderTime = 10 * $questionNumber;
echo $borderTime - $elapsed;
exit(0);
with mocked GET & db: https://3v4l.org/MId0K
then in js just call this script with user identifier and question number. when less than zero is returned, move user to the next question.
js:
$.ajax('http://localhost/your_php_script.php?user='+user+'&question='+questionNumber).done(
function(response){
if (response < 0) {
//move to the next q.
} else {
//show remaining time?
}
});
with asking backend to get time, there is risk of waiting too long for an answer from php (when many users are completing the poll)
I have a popup which is loaded after 30 seconds of viewing the homepage. Is it possible to have it load after 30 seconds of browsing the site and not just a particular page?
Thanks.
Update:
Current code still only loads the box after 30 seconds on each page load
var myDaemon = '';
localStorage.setItem('myTimestamp', Date.now());
if(myDaemon) clearInterval(myDaemon);
myDaemon = setInterval(function(){
var TimeDiffinSeconds = (Date.now() - localStorage.myTimestamp) / 1000;
if( TimeDiffinSeconds > 30){
requestcallback();
clearInterval(myDaemon);
localStorage.myTimestamp = Date.now();
}
},1000);
function requestcallback(){
// localStorage.clear();
var popup
if(localStorage["popup"] != null){
var timestamp = new Date().getTime(),
last_here = new Date();
last_here.setTime(localStorage["popup"]);
var current = last_here.getTime() + (7 * 24 * 60 * 60 * 1000);
if(current < timestamp){
popup = setTimeout(showPopup, 1);
}
}
else{
popup = setTimeout(showPopup, 1);
}
function showPopup(){
jQuery('.overlay').fadeIn();
clearTimeout(popup);
}
jQuery('.overlay .close').click(function(){
jQuery('.overlay').fadeOut();
var current = new Date().getTime();
localStorage["popup"] = current;
});
}
You could use Local Storage in order to save a time-stamp the moment the user visits the site , and then code a simple SetInterval to check that timestamp in specific intervals. If the difference between the current timestamp and the one saved is more than 30 seconds , you can launch your popup.
This is tricky with Javascript though. Depending on your Sites Design a different Approach is required. Also if it is for Security reasons , this is best done with AJAX and Validation through a Server. Javascript can be easily manipulated / prevented from a user and your code can be easily avoided.
A simple Example to get you going :
At your index page insert the following code :
<script>
var myDaemon = '';
localStorage.setItem('myTimestamp', Date.now());
</script>
We have declared a "var myDaemon = '';" so that we can hold our Daemons IDs in there and effectively Clearing them from any of our pages later.
Then at the Pages that you want to check for activity insert the following code :
if(myDaemon) clearInterval(myDaemon);
myDaemon = setInterval(function(){
var TimeDiffinSeconds = (Date.now() - localStorage.myTimestamp) / 1000;
if( TimeDiffinSeconds > 30){
alert('You have been browsing for more than 30 Seconds');
clearInterval(myDaemon);
localStorage.myTimestamp = Date.now();
}
},1000);
The if(myDaemon) clearInterval(myDaemon); is there to make sure we do not overlap Daemons and end up with a million of Alerts after visiting a few pages.
The clearInterval(myDaemon); after the alert is there to make sure that we stop the Daemon when we reach our goal.
The localStorage.myTimestamp = Date.now(); is there to make sure we reset our localstorage to a new Timestamp , in order to recalculate the activity of the user (if needed).
1) Define cookie functions (copy from w3school)
function setCookie(cname, cvalue, exdays) {...}
function getCookie(cname) {...}
function checkCookie() {...}
2) Create cookie if user doesn't have one
getCookie('user_first_visited') || setCookie('user_first_visited', Date.now());
3) Loop detecting if user visited over 30 seconds
if (!getCookie('user_popup_triggerred')) {
var loopDetect = setInterval(function(){
var TimePast = (Date.now() - getCookie('user_first_visited')) / 1000;
if( TimePast > 5){
alert('Browsed any page more than 5 Seconds');
clearInterval(loopDetect);
setCookie('user_popup_triggerred', 1);
}
}, 1000);
}
See jsfiddle, you can try it on two pages and you should not get popupBox on page reload after triggered once. Clean your browser cookie to try again.
I'm making a webpage where user events are logged in.
To test the feature I made a small, independant webpage with a teaxtarea and a text input. The events logged are those performed on the input element.
I want to prevent the same event text to be shown multiple times in a row, but I can't seem to prevent them from showing up!
I also want to add a line to separate event groups 0.5 seconds after no other event happened, but the line seems to appear on every event trigger, evenif I use clearTimeout with the timeout ID.
Basically: I don't want any line to be repeated. If the last line is a separator line, then it must not add another one. Yet it doesn't see to work.
JSFiddle Demo
Here is my code:
JavaScript
var timerID = 0;
function addSeparateLine()
{
document.getElementById('listeEvenements').value += "--------------------\n";
}
function show(newEventText)
{
var eventListField = document.getElementById('listeEvenements');
var eventList = [];
if (eventListField.value.length > 0)
{
eventList = eventListField.value.split("\n");
}
var eventCounter = eventList.length;
if (eventList[eventCounter - 2] == newEventText)
{
clearTimeout(timerID);
newEventText = "";
}
timerID = setTimeout(addSeparateLine, 500);
if (newEventText !== "")
{
eventListField.value += newEventText + "\n";
}
return true;
}
HTML
<fieldset id="conteneurLogEvenements">
<legend>Events called from HTML attribute</legend>
<textarea id="listeEvenements" rows="25"></textarea>
<input id="controleEcoute" type="text" onBlur="show('Blur');" onchange="show('Change');" onclick="show('Click');" onfocus="show('Focus');" onMousedown="show('MouseDown');" onMousemove="show('MouseMove');" onMouseover="show('MouseOver');" onkeydown="show('KeyDown');"
onkeypress="show('KeyPress');" onkeyup="show('KeyUp');" />
</fieldset>
http://jsfiddle.net/z6kb4/2/
It sounds like what you want is a line that prints after 500 milliseconds of inactivity, but what your code currently says to do is "print a line 500 milliseconds after any action, unless it gets canceled". You can get better results by structuring the code more closely to your intended goal.
Specifically, instead of scheduling a new timeout every time an event occurs, simply start a loop when the first event occurs that checks the time that has elapsed since the most recent event received and then prints a line when the elapsed time exceeds the desired threshold (500 milliseconds). Something like:
function addSeparateLine() {
var elapsed = new Date().getTime() - lastEventTime;
if (elapsed >= 500) {
document.getElementById('listeEvenements').value += "--------------------\n";
clearInterval(timerID);
timerID = -1;
}
}
...and then you schedule it like:
if(newEventText !== "") {
lastEventTime = new Date().getTime();
eventListField.value += newEventText+"\n";
if (timerID == -1) {
timerID = setInterval(addSeparateLine,100);
}
}
Working example here: http://jsfiddle.net/z6kb4/4/
Because you are not actually stopping the show function in any way. The clearTimeout only applies to the separator add. I have updated your fiddle. You need to wrap your function with
if (+new Date() - lastfire < 500) return;
and
lastfire = +new Date();
(before the last return--see the updated fiddle). Also, make sure to stick the global definition var lastfire = -1; somewhere up top.
As I don't have much knowledge of javascript and I need your help. My problem is like this:
I am using setInterval() for increasing the value of i every after 1 minutes and I am using this code:
var i = minutes;
function decrementMin() {
if(i>=0)
{
i--;
}
if(i==0)
{
alert('Minute = Congratulation your time begin now!');
}
document.getElementById('minutes').innerHTML = i + "minutes";
}
setInterval('decrementMin()',60000);
The problem is I want to show first message in <div id='minutes'></div> when page loads, but it shows the message after 1 minutes interval. If there is something that I am missing in my code please let me know.
Your problem is that you are setting the interval before the first message is displayed. Instead, you can call the function straight away and then set the interval. Also, you need to clear the interval once you've reached 0:
var i = minutes;
var intID;
function decrementMin() {
if(i>=0)
{
i--;
}
if(i==0)
{
clearInterval(intID);
alert('Minute = Congratulations my friend your time begins now!');
}
document.getElementById('minutes').innerHTML = i + "minutes";
}
decrementMin();
intID = setInterval(decrementMin, 60000);
This way you call your function straight away, and then set it to run every minute. Once you reach 0, you clear the interval so that the function doesn't count to "-1", etc.
I've seen some really nice looking jQuery plugins to count down the number of day, hours, minutes and seconds. They use images and look great.
But I'm looking for a simple little countdown that populates a div with the number of seconds remaining.
I'm going to use it in conjunction with:
function submitform() {
document.forms[0].submit();
}
jQuery(function($) {
setInterval("submitform()",20000);
});
I just want something real unobtrusive in the corner somewhere to let them know that the page is about to refresh all by itself.
First off, setInterval is used when you want to fire a function at set intervals, for example once every twenty seconds. For one-off events use setTimeout.
Here is a lightweight solution for you, assuming you have a div with an id of countdown:
$(function() {
var seconds = 20;
setTimeout(updateCountdown, 1000);
function updateCountdown() {
seconds--;
if (seconds > 0) {
$("#countdown").text("You have " + seconds + " seconds remaining");
setTimeout(updateCountdown, 1000);
} else {
submitForm();
}
}
});
function submitForm() {
document.forms[0].submit();
}
I just wrote a countdown for a project this week. It's just javascript, no jQuery needed.
Just pass the id of the div you want to place the countDown in, and the end and start time in milliseconds (or you can change how the Date params work, I had the dates in ms on the page already, so I passed them into the function, but you could do it differently):
<div id="countDownDiv"></div>
<script type="text/javascript">
countDown("countDownDiv",1281239850163, new Date().getTime());
</script>
And here's the function:
function countDown(id, end, cur){
this.container = document.getElementById(id);
this.endDate = new Date(end);
this.curDate = new Date(cur);
var context = this;
var formatResults = function(day, hour, minute, second){
var displayString = [
'<div class="stat statBig"><h3>',day,'</h3><p>days</p></div>',
'<div class="stat statBig"><h3>',hour,'</h3><p>hours</p></div>',
'<div class="stat statBig"><h3>',minute,'</h3><p>minutes</p></div>',
'<div class="stat statBig"><h3>',second,'</h3><p>seconds</p></div>'
];
return displayString.join("");
}
var update = function(){
context.curDate.setSeconds(context.curDate.getSeconds()+1);
var timediff = (context.endDate-context.curDate)/1000;
// Check if timer expired:
if (timediff<0){
return context.container.innerHTML = formatResults(0,0,0,0);
}
var oneMinute=60; //minute unit in seconds
var oneHour=60*60; //hour unit in seconds
var oneDay=60*60*24; //day unit in seconds
var dayfield=Math.floor(timediff/oneDay);
var hourfield=Math.floor((timediff-dayfield*oneDay)/oneHour);
var minutefield=Math.floor((timediff-dayfield*oneDay-hourfield*oneHour)/oneMinute);
var secondfield=Math.floor((timediff-dayfield*oneDay-hourfield*oneHour-minutefield*oneMinute));
context.container.innerHTML = formatResults(dayfield, hourfield, minutefield, secondfield);
// Call recursively
setTimeout(update, 1000);
};
// Call the recursive loop
update();
}