JS Time Tracker not working as expected - javascript

I have a timer mainly using javascript, currently the start/stop functionality works fine. When user hits "Stop" button it takes the time from the #time element, converts it to decimal value and updates the hidden #counter element. For example an 1 and a half hours would be converted to 1.50
My problem is I also want to allow users to edit the time manually so I have a little plugin that was created to do allow for this.
There are 2 problems:
If a user manually adds their time by double clicking the element and adjusting then were to hit save, the #counter element has not be updated so it is submitting the time as 0.
If a user were to manually set their time and then hit the Start button, the clock starts from 0 instead of the time they specified.
I have a JS Fiddle available here: https://jsfiddle.net/pkj7wyLu/
Toward the bottom of the JS block in that fiddle you will see:
//implement plugin
$('span#time').editable().on('editsubmit', function (event, val) {
console.log('text changed to ' + millisecondsToHours(val));
});
which I believe is the event that fires each time the user manually enters time.
Question: How can I make it where when someone manually enters time that it automatically updates the #counter field with the converted values and if they press start it starts from that time?
What I tried: I tried playing with the format(Time) function and have it currently trying to print the value to the console but I am not getting results

I have created an override method on your clsStopwatch class, like so:
this.override = function(time) {
lapTime = time;
}
This will update the lapTime, passing in a time in milliseconds. To do this I created a new function which accepts a string:
function stringToMilliseconds(str) {
var a = str.split(':'); // split it at the colons
var seconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]);
return seconds * 1000;
}
This will return the number of milliseconds from the edited string in the id #time element span.
Finally, I updated the submit editable event to call the override:
$('span#time').editable().on('editsubmit', function (event, val) {
x.override(stringToMilliseconds(val));
});
Here is the updated JSFiddle
Hope that helps.

Related

How can I show automatically make an element appear/disappear based on current time in AngularJS?

Is there another way to automatically have elements appear and disappear at a certain time than via timeout()? Like ng-if="system.Time>12:00:00" in pseudo code. Preferably only done with html.
What I am aiming at is an offer valid for one hour for instance.
Maybe function like this could be of help:
function timeChecker(){
if(/*check if item should be visible*/){
visible = true
} else {
visible = false
}
}
// your timeChecker function will be runned every minute so you can implement more complex logic if needed
var interval = setInterval(timeChecker, 1 * 60 * 1000 /*that would be one minute*/);
// just remember to clear interval when you destroy component
clearInterval(interval);

Increment Value over a Duration on Update

I'm trying to make a script to increment a number to the selected number on every select change. For example, if the user selects 30, I want the number to increase at a rate of 30 values per second so it reaches 30 in one second.
I don't know what went wrong, but when executing this script, it only increments on the first page load but with no value change.
https://jsfiddle.net/User1010/b7znc3fL/
var valueElement = document.getElementById('value');
var option = document.getElementById('option');
var start = 0;
var end = parseFloat(option.innerHTML);
var duration = 1000; // In milliseconds (divide by 1000 to get seconds).
var framerate = 50; // In milliseconds (divide by 1000 to get seconds).
var toAdd = ( ( end - start ) * framerate ) / duration;
var interval = setInterval(function() {
var currentValue = parseFloat(valueElement.innerHTML);
if (currentValue >= end) {
clearInterval(interval);
return;
}
valueElement.innerHTML = (!isNaN(currentValue) == true ? (currentValue + toAdd).toFixed(2) : toAdd);
}, framerate);
You may be overthinking this task. I also found there were errors and things to change in the console and the JSFiddle. For example, there is no element with the name option.
https://www.khanacademy.org/computing/computer-programming/html-css-js/html-js-dom-animation/p/animating-dom-with-setinterval
https://www.khanacademy.org/computer-programming/spin-off-of-challenge-stopwatch/6144204027232256
Let's start with something basic: A Stopwatch
Define variables for better convenience, for better, more common practice, and for higher efficiency
A variable that can be called counterEl initializing the span element using document.getElementById() on the id 'daily'.
A variable that can be called selectEl initializing the select element using document.getElementById() on the id 'value'.
A type null variable that can be called currentTime which will turn counterEl into a float data type by calling parseFloat() on countEl.textContent.
A type null variable called stopwatch that will be initialized when you use setInterval.
I also used the linking Stack Overflow question for help
Add an event listener to the select element for every time its value changes like so: selectElement.addEventListener("change", myFunction);
Create a global function resetStopwatch() {}
Set countEl.textContent to 0.
Just for good measure, set currentTime to 0 as well.
stopwatch = window.setInterval(countUp, 1000);
Create the global countUp function
Everything here is explained in the comments.
// Turns the value into a float so it can be incremented and compared (textContent is a string)
currentTime = parseFloat(seconds.textContent);
// Add 1 second every time function is called
seconds.textContent = currentTime + 1;
if (seconds.textContent >= selectElement.value) {
window.clearInterval(stopwatch); // Stops the stopwatch if the seconds
reached the selected option
console.log("My time has been cleared");
}
Now let's slightly tweak this to make it a 'reverse stopwatch'
In the setInterval, you want it to increment that many in one second, so you would change the invocation to
stopwatch = window.setInterval(countUp, 1000/incrementRate.value);
Use my JS Fiddle for guidance in solving your problem:
https://jsfiddle.net/404_Error/z0t4spob/
Looks like you just need to bind a change event handler to your select/option.
Reference MDN's Event documentation on adding this to your script to handle the changes and update of the value.
Just a heads up, if you want to use a framework like jQuery, the process and script can be simplified drastically.

display timer for every page starting from(00sec) in javascript

I created a quiz application using PHP. In that application I display one question per page. When user clicks on the next button, it displays the next question, one chosen randomly from database. So for that I want to display time.
But my problem is:
I want to display a timer from starting only seconds. When user clicks on the next button, first question timer is going to be stored in database and the timer will start(from 00:00) for the second question.
I tried a lot, but I don't have any idea how to do this.
It is better to use window.setInterval() in order for the timer to not rely on the system time. .setInterval will fire every n milliseconds. You can just increment using that
You can have:
var secondsCounter = 0;
function quizTimer(){
secondsCounter++;
}
window.setInterval(quizTimer, 1000);
Then you can display the time easily by using
myTimerElement.innerHTML = "Seconds Passed: " + secondsCounter;
Now you just have to do a little tweaking to make it appear in time format MM:SS
it could be
myTimerElement.innerHTML = minutesCounter + " : " + secondsCounter;
now just do some formatting methods or conditions to make the counter variables display two digits.
EDIT:
Check this snippet:
var secondsCounter = 0;
var startTime;
function restartTimer(){
secondsCounter = 0;
window.clearInterval(startTime);
startTime = window.setInterval(quizTimer, 1000);
}
function quizTimer(){
secondsCounter++;
document.getElementById('timer').innerHTML = "Seconds Passed: " + secondsCounter;
}
document.getElementById('btnsub').addEventListener('click', restartTimer);
<span id='timer'></span>
<button id='btnsub'>Submit</button>

JQuery Clock / Timer since the page was loaded (even if user changes time on his computer)

I've modified the code from SO, provided by SLaks so make it work even if the user changes the time on his computer.
The time for <div id="timer"></div> still showing the real time since the page was loaded (even if the user changes the time on his computer).
When time changed, the alert appears (please see the code below).
The problem is: once time is changed, the alert appears the infinite number of times every second (but only one time is expected). Why is this happening?
$(document).ready(function () {
var start = new Date;
var end = (new Date - start) / 1000;
setInterval(function () {
if (Math.abs(end - (new Date - start) / 1000 )>1) {
start = new Date - end * 1000;
alert(Math.abs(end - (new Date - start) / 1000 ));
}
end = (new Date - start) / 1000;
$('#timer').text(end + " Seconds");
}, 100);
});
It's actually pretty simple - script execution is paused until the messagebox is closed. When you close it, the timer is already delayed and the condition is true again. You can test it yourself by duplicating the alert[...] line: if you close the first message fast enough, the second one will show something below 1.
Just replace alert with some HTML-based floating window and everything will be fine.

Canvas scroll animation not working correctly

I'm building a gantt chart style timeline using html canvas element.
I am currently attempting to add the functionality which allows the user to click a next/prev button to have the gantt chart scroll to display earlier or later times.
The way I am doing this is to have a span.adjustTime where the id holds a value in seconds for the time to be adjusted (eg 86400 for one day).
I am trying to animate the scrolling so it looks like a scroll, rather than jumping ahead by one day.
I have a small problem in my timing calculation, but the script below is not animating, but rather jumping directly to the final time.
I do have the draw function running on a separate setInterval which updates every second, so I'm hoping it isn't an issue of conflicting timers on the same function on the same element and data.
jQuery('span.adjustTime').click(function() {
var adjustBy = parseInt(jQuery(this).attr('id').replace('a', ''));
var data = jQuery('img#logo').data();
for(var m = 1; m >= 30; m++) {
gantt.startUnixTime = gantt.startUnixTime + (adjustBy * (m * 0.001));
var moveTimer = setTimeout(function() {
draw(document.getElementById('gantt'), data, gantt);
}, 1000);
if (m == 30) {
clearTimeout(moveTimer);
}
}
});
In the for loop you are calling setTimeout 30 times, each time with the same timeout value of 1000. So after 1000 milliseconds 30 scheduled functions will execute at almost the same time. I suppose this is not what you intended. If you wanted an animation of 30 frames over 1000 milliseconds, the setTimeout should look something like:
setTimeout(function() { ... }, 1000 / 30 * m)
Also note that all 30 scheduled functions will see the same gantt.startUnixTime value, since the same object (gantt) is passed to all of them, and when they execute, the for loop has finished already long ago.

Categories

Resources