Browser Bug showing time text on input - javascript

I am dealing with the following puzzle and I cannot understand why it is happening.
I have the following [I believe to be] equivalent pieces of javascript code, but one does not work as expected (notice the Console.Log):
Updates the UI a single time, then unexpectantly stops updating : http://jsfiddle.net/silentwarrior/1m0v6oj1/
jQuery(function () {
var isWorking = true;
if (isWorking) {
var timeEnd = 1431220406000; // generated from php
var timeNow = 1431210557000; // generated from php
var counter = 1;
var t = "";
setInterval(function () {
try {
var c = timeEnd - timeNow - counter;
console.log(c);
var d = new Date(c);
if (c <= 1) {
window.location.href = window.location.href;
return;
}
t = "";
if (d.getHours() > 0) {
t += d.getHours() + "h ";
}
if (d.getMinutes() > 0) {
t += d.getMinutes() + "m ";
}
t += d.getSeconds();
jQuery("#factory_start_prod").val("Working ... " + t + "s left");
counter = counter + 1;
} catch (e) {
}
}, 1000);
}
});
Updates the UI constantly as expected: http://jsfiddle.net/silentwarrior/n3gkum2e/
jQuery(function () {
var isWorking = true;
if (isWorking) {
var timeEnd = 1431220406000;
var timeNow = 1431210557000;
var counter = 1;
var t = "";
setInterval(function () {
try {
var c = timeEnd - Date.now();
console.log(c);
var d = new Date(c);
if (c <= 1) {
window.location.href = window.location.href;
return;
}
t = "";
if (d.getHours() > 0) {
t += d.getHours() + "h ";
}
if (d.getMinutes() > 0) {
t += d.getMinutes() + "m ";
}
t += d.getSeconds();
jQuery("#factory_start_prod").val("Working ... " + t + "s left");
counter = counter + 1;
} catch (e) {
}
}, 1000);
}
});
The only difference from each other is that, the one that works uses Date.now() to get the current timestamp, while the other one uses a pre-built time stamp.
Why would one example update the text in the input correctly while the other wouldn't?
PS: it is important to me to use generated timestamps instead of Date.now() in order to not depend on the users system when calculating the time left.

Your first example is working, however with each iteration you are only subtracting 1 from the timestamp value, which is equivalent to 1ms. Hence the value never appears to change unless you wait a really long time. You need to increment the counter by 1000 on each iteration for a second to be counted:
counter = counter + 1000;
Updated fiddle

Related

Timer for individual <div>

I'm currently trying to set a timer for each div created, whereby each div has a background color of green or red depending on if there are detections in the webRTC video. Is there a way to assign a timer to the divs individually? Or maybe to only check for my own video? I've tried something like below, but it does not work when there are more than 1 people in the call, as "time" will be a global variable. I've also tried something like time = Math.ceil((time+1)/checkerBox.length) , but it does not seem to work too. Any pointers will be helpful
function checker(){
var time =0;
var timer = setInterval(function (){
for(var i=0;i<checkerBox.length;i++){
if(checkerBox[i].style.backgroundColor=="red"){
time = time + 1;
console.log("Box" + videoNum[i].innerHTML + " is not present for : " + checkerBox[i].innerHTML + " seconds");
}else{
time = 0;
}
//Exceed time
if(checkerBox[i].innerHTML == 30){
setTimeout(function(){
takeScreenshot(videoNum[i-1]);
}, 100);
time = 0;
}
checkerBox[i].innerHTML = time;
}
},1000)
}
Update : I ended up using arrays
var takenFrom;
var d = new Date();
let timeKeep = new Array(0,0,0,0,0,0,0,0,0,0,0);
let screenShots = new Array(0,0,0,0,0,0,0,0,0,0,0);
function checker(){
timer = setInterval(function (){
for(var i=0;i<=(checkerBox.length)-1;i++){
tableRow[i+1].cells[2].innerHTML = timeKeep[i]
tableRow[i+1].cells[3].innerHTML = screenShots[i]
if(flag[i].innerHTML=="0"){
checkerBoxFalse(checkerBox[i]);
timeKeep[i] = timeKeep[i] + 1;
console.log("Box" + videoNum[i].innerHTML + " is not present for : " + tableRow[i+1].cells[2].innerHTML + " seconds");
if(tableRow[i+1].cells[2].innerHTML == 10 ){
takenFrom = "Box" + videoNum[i].innerHTML + "minute" + d.getMinutes() + " room" + ROOM_ID
takeScreenshot(videoNum[i],takenFrom);
screenShots[i] = screenShots[i] + 1;
timeKeep[i] = 0;
}
} else if(flag[i].innerHTML== "1"){
checkerBoxTrue(checkerBox[i]);
timeKeep[i] = 0;
}
}
},1000)
}
Yes:
for (let div of divs) {
setInterval(function() {
//do something with div
}, 1000);
}
let is block scoped, so each setInterval will have its own div.

Ajax Request Not Always Consistent

I have been developing a site that will provide schedules created by people. I'm using Alienware to develop it and the ajax code works perfectly on the laptop all of the time. I am using IE. However, if I access my site on my Samsung Smart TV or my HTC U11 phone, Ajax isn't consistent. It displays the data I am requesting, however, when I sum up a total of hours for the week, it sometimes displays the correct hours, or sometimes shows 0 hours, when the user is scheduled for the week. Why is it inconsistent between devices? I know that Ajax is recommended for IE. As I said, though, it sometimes will display the correct total weekly hours, and other times it will just show zero. This issue isn't occurring on my Alienware.
I've already tried using onload instead of onreadystatechange. I've set the request to asynchronous and synchronous. Whether it's set to true or false, on my other devices, it fails to be consistent. I've tried it as a post and get method, and both also are inconsistent. What is wrong with my code?
function getThisWeek(str5) {
lastDate = new Date(str5);
// getting dates for this week to be displayed...
this.math = dayInput.length - 1;
this.math0 = 0 - new Date(str5).getDay();
// getting week total hour length, to determine how many times this code executes...
weekSum = 0;
totals = [];
for (this.i = 0; this.i < weekTotalHours.length; this.i++) {
str3 = this.i;
this.date = new Date(str5);
for (this.ii = (this.i * (7)) - new Date().getDay(); this.ii < (7 * (this.i + 1)) - new Date().getDay(); this.ii++) {
totalHours = 0;
this.date = new Date(str5);
this.date = new Date(this.date.setDate(this.date.getDate() + (this.ii)));
// which element position the total daily hours belongs to when displaying them...
this.pos = this.ii + new Date().getDay();
thisDayChart[this.pos].innerHTML = "";
// displaying the date
dayInput[this.pos].innerHTML = this.date.getDate();
// highlighting today's date...
if (this.date.getDate() == new Date(str5).getDate() && this.date.getMonth() == new Date().getMonth()) {
dayInput[this.pos].style.color = "white";
dayInput[this.pos].style.backgroundColor = "silver";
dayInput[this.pos].style.borderRadius = "0px";
thisDay[this.pos].style.border = "2px double lightblue";
} else {
dayInput[this.pos].style.color = "";
dayInput[this.pos].style.backgroundColor = "";
dayInput[this.pos].style.borderRadius = "";
thisDay[this.pos].style.border = "";
}
// getting schedule from database...
this.xmlhttp = new XMLHttpRequest();
this.xmlhttp.pos = this.pos;
this.xmlhttp.ipos = this.i;
this.xmlhttp.d = months[this.date.getMonth()] + " " + this.date.getDate() + ", " + this.date.getFullYear();
this.xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//alert(this.responseText);
dayInput[this.pos].m = months[new Date(this.d).getMonth()];
dayInput[this.pos].weekDay = days[new Date(this.d).getDay()];
// how many weeks in the year is user...
this.islpyr = new Date(this.d);
this.islpyr = this.islpyr.setMonth(1);
this.islpyr = new Date(new Date(this.islpyr).setDate(29));
if (this.islpyr.getMonth() == 2) {
mlens[1] = 28;
} else {
mlens[1] = 29;
}
// getting total amount of days for the year...
this.yrlen = 0;
for (this.iii = 0; this.iii < mlens.length; this.iii++) {
this.yrlen += mlens[this.iii];
}
// getting total weeks
this.wklen = this.yrlen / 7;
this.wklen = Math.round(this.wklen);
this.week = 0;
for (this.iii = 0; this.iii < new Date(this.d).getMonth(); this.iii++) {
this.week += mlens[this.iii];
}
this.week += new Date(this.d).getDate();
this.week /= 7;
this.week = Math.round(this.week) + 1;
// rounding and displaying current week number...
if (new Date(this.d).getDay() == 0) {
myDayWrapper[this.ipos].weekLabel = "Week " + this.week + " of " + this.wklen;
}
if (this.pos == 0) {
weekDisplay[0].innerHTML = myDayWrapper[0].weekLabel;
}
// which day of the year it is... how many days in the year is the user...
this.yrpos = 0;
for (this.iv = 0; this.iv < new Date(this.d).getMonth(); this.iv++) {
this.yrpos += mlens[this.iv];
}
this.yrpos += new Date(this.d).getDate();
thisDayTitle[this.pos].innerHTML = "Day " + this.yrpos + " of " + this.yrlen;
totalHours = 0;
this.schedule = "" + this.responseText;
// if user is unscheduled, do this first... 'undefined' literally means there isn't a schedule for that specific day.
if (this.schedule.search("Undefined") >= 0) {
this.elem = document.createElement("div");
this.elem.setAttribute("class","not_scheduled");
this.elem.innerHTML = "Unscheduled";
thisDayChart[this.pos].appendChild(this.elem);
this.elem = document.createElement("div");
this.elem.setAttribute("class","pick_up_shift_btn");
this.elem.innerHTML = "Claim Shifts";
this.elem.i = this.pos;
this.elem.ipos = this.ipos;
this.elem.onclick = function() {
popUpWrap[1].style.display = "block";
this.datesd = [];
for (this.i = this.ipos * 7; this.i < 7 * (this.ipos + 1); this.i++) {
this.datesd.push(dayInput[this.i].innerHTML);
}
for (this.i = 0; this.i < 7; this.i++) {
shiftClaimDate[this.i].innerHTML = this.datesd[this.i];
popUpShiftDay[this.i].innerHTML = dayInput[this.i].weekDay;
this.strrr = "" + dayInput[this.i].m;
this.strrr = this.strrr.substring(0,3);
shiftClaimMonth[this.i].innerHTML = this.strrr;
}
}
thisDayChart[this.pos].appendChild(this.elem);
if (totals.length - 1 == this.pos) {
} else {
totals.push(0);
}
} else {
// getting daily total...
this.schedule = this.schedule.split(",");
for (this.iii = 0; this.iii < this.schedule.length; this.iii++) {
this.str = "" + this.schedule[this.iii];
this.str = this.str.split("=");
this.dateString = "December 22, 1991";
switch (this.str[0]) {
case "shift_start":
this.start = new Date(this.dateString + " " + this.str[1]);
this.end = this.schedule[this.schedule.length - 1] + "";
this.end = this.end.split("=");
this.end = new Date(this.dateString + " " + this.end[1]);
this.hours = (this.end.getHours() - this.start.getHours()) * 60;
this.hours = this.hours - (this.start.getMinutes() + this.end.getMinutes());
this.hours /= 60;
totalHours += this.hours;
weekSum += totalHours;
break;
case "break_start":
this.start = new Date(this.dateString + " " + this.str[1]);
this.end = this.schedule[this.iii + 1] + "";
this.end = this.end.split("=");
this.end = new Date(this.dateString + " " + this.end[1]);
this.hours = (this.end.getHours() - this.start.getHours()) * 60;
this.hours = this.hours - (this.start.getMinutes() + this.end.getMinutes());
this.hours /= 60;
weekSum -= this.hours;
totalHours -= this.hours;
this.s = "s";
if (totalHours == 1) {
this.s = "";
}
thisDayChart[this.pos].innerHTML = totalHours + " hour" + this.s;
break;
}
}
}
weekTotalHours[this.ipos].innerHTML = "Week Total: " + weekSum;
//alert(weekSum);
// displaying hour totals...
if (new Date(this.d).getDay() == 6) {
weekSum = 0;
}
totalHours = 0;
}
}
this.xmlhttp.open("GET","/js/data/schedule.html?date="+ months[this.date.getMonth()] + " " + this.date.getDate() + ", " + this.date.getFullYear(),false);
this.xmlhttp.send();
}
}
}
I expect every device to be consistent with the hour total it should be displaying, on every device that Ajax should work on.

JavaScript - Delay execution of certain javascript

I need help in delaying the execution of my javascript.(not making the javascript to execute right after the webpage is being loaded) I wish to execute the javascript only after 10s after the webpage is being loaded. How can I do that? This is the script.
<script>
var interval = 10000;
var current_index = -1;
var sales_feeds = [];
var showtime = 5000;
<?php $s = get_option('wc_feed_delay_between_popups_appear');
if (!$s) {
$s = 5000;
}
?>
function hide_prev_feed_notify(index)
{
if( sales_feeds.eq(current_index).length > 0 )
{
sales_feeds.eq(current_index).animate({bottom: '-90px'}, 500);
}
}
function show_live_feed_notify(index)
{
sales_feeds.eq(index).animate({bottom: '10px'}, 1000);
current_index = index;
}
function show_next_live_notify()
{
if( (current_index + 1) >= sales_feeds.length )
{
current_index = -1;
}
//add randomness
current_index = (Math.floor(Math.random() * (sales_feeds.length + 1))) - 1;;
if( window.console )
console.log('will show ' + (current_index+1));
show_live_feed_notify(current_index + 1);
setTimeout(function() { hide_prev_feed_notify(current_index + 1); }, showtime);
}
function stop_live_notify()
{
removeInterval(inverval);
}
function readCookie(name)
{
var nameEQ = escape(name) + "=";
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, c.length);
if (c.indexOf(nameEQ) === 0) return unescape(c.substring(nameEQ.length, c.length));
}
return null;
}
jQuery(function()
{
jQuery('.wc_feed_close_btn').click(function()
{
var days = 30;
var date = new Date();
date.setTime(date.getTime() + (days *24 *60 *60 *1000));
if(window.console)
console.log(date.toGMTString());
document.cookie = 'wc_feed_closed=true; expires=' + date.toGMTString() + ';';
jQuery('.live-sale-notify').css('display', 'none');
clearInterval(interval);
return false;
});
sales_feeds = jQuery('.live-sale-notify');
show_next_live_notify();
interval = setInterval(show_next_live_notify, (showtime + <?php print $s + 100; ?>));
});
</script>
Note: I want to delay the following execution.
function show_live_feed_notify(index)
{
sales_feeds.eq(index).animate({bottom: '10px'}, 1000);
current_index = index;
}
I tried inserting
var delay = 10000;
or
var interval = 10000;
none of them seem to work.
I also tried
setTimeout (function(); 3000);
it came out with uncaught syntax error.
Please Help me guys!
Note: I'm new to js/php coding...
Looking at your code, I think you should just remove the line
show_next_live_notify();
at the bottom of your script. It automatically executes everything right upon start instead of letting setInterval do its job
To delay the whole script, replace the last two lines in the jQuery call with something like this:
function startMe() {
interval = setInterval(show_next_live_notify, (showtime + <?php print $s + 100; ?>));
}
setTimeout(startMe, 10000);
You function name is show_live_feed_notify, and you tried to use setTimeout. Therefore I suggest you to try the following:
var delay = 10000; // 10 seconds
setTimeout(function() {
show_live_feed_notify(current_index + 1);
}, delay )

Javascript: Grab an array and sum all values

In my project, users can add timecode in and out points for their project, and the project automatically figures out the total duration of the timecode. But I want to add a function that will take all the available timecode durations, convert them to seconds, add them together, then convert the final number back to timecode and put it in a text input.
This is my code, but I keep getting syntax errors:
function timeToSeconds(t) {
var tc = t.split(':');
return parseInt(tc[0])*3600 + parseInt(tc[1])*60 + parseInt(tc[2]);
}
function tcDuration(tcin, tcout) {
function z(n){return (n<10?'0':'') + n;}
var duration = timeToSeconds(tcout) - timeToSeconds(tcin);
var hoursmins = Math.floor(duration / 60);
return z(Math.floor(hoursmins/60)) + ':' + z(hoursmins % 60) + ':' + z(duration % 60);
}
// Run this function every time a film_tc_out cell is changed
function film_tc_Duration() {
if (document.getElementById("film_tc_in").value == '') {var film_tc_in = '00:00:00';} else { var film_tc_in = document.getElementById("film_tc_in").value;}
if (document.getElementById("film_tc_out").value == '') {var film_tc_out = '00:00:00';} else { var film_tc_out = document.getElementById("film_tc_out").value;}
document.getElementById("film_tc_duration").value = tcDuration(film_tc_in, film_tc_out);
}
// Run this function every time a src_tc_out cell is changed
function src_tc_Duration() {
if (document.getElementById("src_tc_in").value == '') {var src_tc_in = '00:00:00';} else { var src_tc_in = document.getElementById("src_tc_in").value;}
if (document.getElementById("src_tc_out").value == '') {var src_tc_out = '00:00:00';} else { var src_tc_out = document.getElementById("src_tc_out").value;}
document.getElementById("src_tc_duration").value = tcDuration(src_tc_in, src_tc_out);
}
// Run this function every time a src_wd_out cell is changed
function src_wd_Duration() {
if (document.getElementById("src_wd_in").value == '') {var src_wd_in = '00:00:00';} else { var src_wd_in = document.getElementById("src_wd_in").value;}
if (document.getElementById("src_wd_out").value == '') {var src_wd_out = '00:00:00';} else { var src_wd_out = document.getElementById("src_wd_out").value;}
document.getElementById("src_wd_duration").value = tcDuration(src_wd_in, src_wd_out);
}
function total_tc_Duration() {
var val = document.getElementsByClassName('.asset_src_tc_duration');
var total_tc = 0;
var v;
for (var i = 0; i < val.length; i++) {
v = timeToSeconds(val[i]);
if (!isNaN(v)) total_tc += v;
}
return (total_tc);
}
function updateAssetTimecode() {
document.getElementById("timecode_total").value = total_tc_Duration();
}
Update: I've rewritten the For Loop to see if that helps - it currently gives me an answer now, although the answer is always "0". It's not spitting out any errors but it seems to think the variable val isn't a number?
Your tcDuration function won't work like you expect. You don't subtract the already calculated hours before doing the minutes calculation and the same with seconds.
function tcDuration(tcin, tcout) {
function z(n){return (n<10?'0':'') + n;}
var duration = timeToSeconds(tcout) - timeToSeconds(tcin);
var hoursmins = Math.floor(duration / 60);
return z(Math.floor(hoursmins / 60)) + ":" + z(hoursmins % 60) + ":" + z(duration % 60);
}

javascript count down to show days?

I have this javascript countdown that will show seconds. I need to know how I can show days in the counter instead of second.
i.e. 1 day, 2 hours left.
this is the code:
<script type="text/javascript">
var MAX_COUNTER = 1000;
var counter = null;
var counter_interval = null;
function setCookie(name,value,days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
expires = "; expires="+date.toGMTString();
}
else {
expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
}
function getCookie(name) {
var nameEQ = name + "=";
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,c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
function deleteCookie(name) {
setCookie(name,"",-1);
}
function resetCounter() {
counter = MAX_COUNTER;
}
function stopCounter() {
window.clearInterval(counter_interval);
deleteCookie('counter');
}
function updateCounter() {
var msg = '';
if (counter > 0) {
counter -= 1;
msg = counter;
setCookie('counter', counter, 1);
}
else {
counter = MAX_COUNTER;
}
var el = document.getElementById('counter');
if (el) {
el.innerHTML = msg;
}
}
function startCounter() {
stopCounter();
counter_interval = window.setInterval(updateCounter, 1000);
}
function init() {
counter = getCookie('counter');
if (!counter) {
resetCounter();
}
startCounter();
}
init();
</script>
at the moment it only shows seconds and it will restart itself once it hits 0.
http://jsfiddle.net/h2DEr/1/
function updateCounter() {
var msg = '';
if (counter > 0) {
counter -= 1;
msg = convertSecondsToDays(counter);
setCookie('counter', counter, 1);
}
else {
counter = MAX_COUNTER;
}
var el = document.getElementById('counter');
if (el) {
el.innerHTML = msg;
}
}
Here is the function that converts seconds to days
function convertSecondsToDays(sec) {
var days, hours,rem,mins,secs;
days = parseInt(sec/(24*3600));
rem = sec - days*3600
hours = parseInt(rem/3600);
rem = rem - hours*3600;
mins = parseInt(rem/60);
secs = rem - mins*60;
return days +" days " + hours +" hours "+mins + " mins "+ secs + " seconds";
}
update: after #sanya_zol's answer and comments from David Smith
since setInterval is not supposed to run every second, you need to change your strategy a little bit. I have modified the fiddle for that as well
Set MAX_COUNTER to a value when you want it to expire.
instead of decreasing the counter by -1, check the current time, subtract it from the expiry date and display it.
EXPIRY_SECONDS = 24*60*60;
MAX_COUNTER = parseInt(new Date().getTime()/(1000)) + EXPIRY_SECONDS;
function updateCounter() {
var msg = '',curTime = parseInt(new Date().getTime()/1000);
if (curTime < MAX_COUNTER) {
msg = convertSecondsToDays(MAX_COUNTER- curTime);
setCookie('counter', MAX_COUNTER- curTime, 1);
}
else {
MAX_COUNTER = parseInt(new Date().getTime()/1000) + EXPIRY_SECONDS;
}
var el = document.getElementById('counter');
if (el) {
el.innerHTML = msg
}
}
counter_interval = window.setInterval(updateCounter, 1000);
The 1000 is value in milliseconds so how many milliseconds are there in a day?
counter_interval = window.setInterval(updateCounter, 1000*60*60*24);
addition to vdua's answer:
Your code is really badly written.
It uses setInterval which counter is not precise (moreover, it have very, very bad precision) - so your counter's second will be equal to 1.05-1.2 real seconds (difference between real time and counter will accumulate).
You should check system time (via (new Date).getTime() ) every time at lower intervals (like 100 ms) to get precise counter.

Categories