jquery event delegation won't work - javascript

So I have this code.
$("#inputs input.time").mask("00:00:00");
$("#inputs input.time").prop('value', '00:00:00');
Number.prototype.padDigit = function () {
return (this < 10) ? '0' + this : this;
}
$('#display').click(function () {
$('#show').show();
});
$('#inputs').on('focus', 'input.time', function () {
$(this).select();
});
$('#append').click(function () {
$('#inputs').after("<input type='text' value='00:00:00' class='time' name='time2' /><br>");
});
$('#inputs').on('keyup', 'input.time', function (event) {
console.log(event);
var t1 = '00:00:00';
var mins = 0;
var hrs = 0;
var sec = 0;
$('#inputs input.time').each(function () {
t1 = t1.split(':');
var t2 = $(this).val().split(':');
//console.log(Number(t1[1]) + Number(t2[1]))
sec = Number(t1[2]) + Number(t2[2]);
secmns = Math.floor(parseInt(sec / 60));
mins = Number(t1[1]) + Number(t2[1]) + secmns;
minhrs = Math.floor(parseInt(mins / 60));
hrs = Number(t1[0]) + Number(t2[0]) + minhrs;
sec = sec % 60;
mins = mins % 60;
t1 = hrs.padDigit() + ':' + mins.padDigit() + ':' + sec.padDigit()
console.log(t1)
});
if (t1 == 'NaN:NaN:NaN') {
t1 = '00:00:00';
}
$('#total').text(t1);
/*****************subtract time*****************/
//new Date(year, month, day, hours, minutes, seconds, milliseconds)
//problem, if the seconds, mins or hrs of total is bigger than the remaining. Unexpected result
var start = $('#rem').text();
var end = $('#total').text();
s = start.split(':');
e = end.split(':');
var se = Number(s[2]) - Number(e[2]);
var sems = Math.floor(parseInt(sec / 60));
var mi = Number(s[1]) - Number(e[1]) - sems;
var mihr = Math.floor(parseInt(mins / 60));
var hr = Number(s[0]) - Number(e[0]) - mihr;
if (se < 0) {
mi = mi - 1;
se = se + 60;
}
if (mi < 0) {
hr = hr - 1;
mi = mi + 60;
}
var result = hr.padDigit() + ':' + mi.padDigit() + ':' + se.padDigit();
if (result == 'NaN:NaN:' + se) {
result = '00:00:00';
}
$('#remain').text(result);
});
#remain,
#total {
background-color: #333;
width: 60px;
height: 20px;
color: #fff;
padding: 0 10px;
}
#show {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<script src="https://raw.githubusercontent.com/igorescobar/jQuery-Mask-Plugin/master/src/jquery.mask.js"></script>
<button id='display'>Display</button>
<div id='show'>Remaining:
<div id='remain'>01:20:30</div>Total:
<div id='total'>00:00:00</div>
<div id='rem'>01:20:30</div>
<br>
<div id='inputs'>
<input type='text' class='time' />
<button id='append'>+</button>
<br>
</div>
</div>
my problem is that the event on('keyup') works fine with .append and the result run on keyup event but if i use.after instead of .append, the code still works but the result will only show if the keyup event is done on the very first input. if the code above won't run, try my JFiddle . It's just the same code as above.

Hope this is what you want!! You need to use insertAfter and insert it after last input in the #inputs div
$('#append').click(function () {
$("<input type='text' value='00:00:00' class='time' name='time2' />").insertAfter("#inputs input:last");
});
Here is the working DEMO
EDIT - 2
Change as below and it will work:
$('#append').click(function () {
$("#inputs").after("<input type='text' value='00:00:00' class='time' name='time2' /><br/>");
});
$(document).on('keyup', 'input.time', function (event) {
console.log(event);
var t1 = '00:00:00';
var mins = 0;
var hrs = 0;
var sec = 0;
$('input.time').each(function () {
t1 = t1.split(':');
var t2 = $(this).val().split(':');
//console.log(Number(t1[1]) + Number(t2[1]))
sec = Number(t1[2]) + Number(t2[2]);
secmns = Math.floor(parseInt(sec / 60));
mins = Number(t1[1]) + Number(t2[1]) + secmns;
minhrs = Math.floor(parseInt(mins / 60));
hrs = Number(t1[0]) + Number(t2[0]) + minhrs;
sec = sec % 60;
mins = mins % 60;
t1 = hrs.padDigit() + ':' + mins.padDigit() + ':' + sec.padDigit()
console.log(t1)
});
if (t1 == 'NaN:NaN:NaN') {
t1 = '00:00:00';
}
$('#total').text(t1);
/*****************subtract time*****************/
//new Date(year, month, day, hours, minutes, seconds, milliseconds)
//problem, if the seconds, mins or hrs of total is bigger than the remaining. Unexpected result
var start = $('#rem').text();
var end = $('#total').text();
s = start.split(':');
e = end.split(':');
var se = Number(s[2]) - Number(e[2]);
var sems = Math.floor(parseInt(sec / 60));
var mi = Number(s[1]) - Number(e[1]) - sems;
var mihr = Math.floor(parseInt(mins / 60));
var hr = Number(s[0]) - Number(e[0]) - mihr;
if (se < 0) {
mi = mi - 1;
se = se + 60;
}
if (mi < 0) {
hr = hr - 1;
mi = mi + 60;
}
var result = hr.padDigit() + ':' + mi.padDigit() + ':' + se.padDigit();
if (result == 'NaN:NaN:' + se) {
result = '00:00:00';
}
$('#remain').text(result);
});
WORKING DEMO
Basically what you are trying to do is you are inserting the inputs
after the #inputs div and you have written code to accept keyup
which are present inside #inputs div. Since you are giving same
class name to all the inputs where you make changes if you refer
only them it is enough. No need to reach them through their parent
div.

Related

How to set an alarm in a countdown project while we are using JavaScript?

I am a new learner. I am making a countdown project that gets input from the user and then countdown the time. It rings an alarm after every 5 seconds. But after getting the end-numbers 00:00 it does not stop. It continuously rings the alarm. Please check the code.
<span id="min">00</span>
<span>:</span>
<span id="snd">00</span>
<audio id="myAudio">
<source src="beep-02.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<button class="btn" id="start" onclick="timer.start();">START</button>
<span class="mx-3"></span>
<button class="btn" id="set" onclick="location.href='time-selecter.html';">SET</button>
<script type="text/javascript">
var hh = localStorage.getItem("a")
var mm = localStorage.getItem("b")
var ss = localStorage.getItem("c")
function yourfunction() {
document.getElementById("hr").innerHTML = hh;
document.getElementById("min").innerHTML = mm;
document.getElementById("snd").innerHTML = ss;
}
window.onload = yourfunction;
//timer
var start_time = 0;
var elapsed_time = 0;
var requested_time;
var timer_inter;
var timer = {
start: function() {
start_time = new Date();
requested_time = toMs(document.getElementById('hr').innerHTML, document.getElementById('min').innerHTML, document.getElementById('snd').innerHTML, 0);
timer_inter = setInterval(function() {
elapsed_time = new Date() - start_time;
document.getElementById('time').innerHTML = toTimeFormat(requested_time - elapsed_time + 1000, 'hh:mm:ss');
//+ 1000ms because the seconds are rounded down, so without it when the timer SHOWS 00:00:00, it will have to wait 1s before stopping
if (elapsed_time >= requested_time) {
timer.stop();
timer.end();
}
}, 0);
},
stop: function() {
clearInterval(timer_inter);
},
end: function() {
document.getElementById('time').innerHTML = '00:00';
}
};
var x = document.getElementById("myAudio");
function yourFunction(){
setTimeout(yourFunction, 5000);
x.play();
}
function pausefn(){
x.pause();
x.currentTime = 0;
}
$("#start").click(function(){
yourFunction();
});
/*------------------------------*/
/*UTILITY*/
/*------------------------------*/
function toTimeFormat(t, format) {
function addDigit(n) {
return (n < 10 ? '0':'') + n;
}
var ms = t % 1000;
t = (t - ms) / 1000;
var secs = t % 60;
t = (t - secs) / 60;
var mins = t % 60;
var hrs = (t - mins) / 60;
ms = (ms < 10) ? '00' : (ms < 100) ? '0' + Math.floor(ms / 10) : Math.floor(ms / 10);
if (format === 'hh:mm:ss') {
return addDigit(mins) + ':' + addDigit(secs);
} else if (format === 'mm:ss:msms') {
return addDigit(mins) + ':' + addDigit(secs) + ':' + ms;
}
}
function toMs(h, m, s, ms) {
return (ms + s * 1000 + m * 1000 * 60 + h * 1000 * 60 * 60);
}
</script>
I am making a countdown project. I tried to stop an alarm when countdown at 00:00 time. But it countinousily rings the alarm untill I close the browser.

javascript function is not working on button click. But working without button click

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

2 decimal time display on audio player

For my audio player, how can I display both times in just 2 decimals?
Right now the counter shows ... 0:7, 0:8, 0:9, 0:10, 0:11
But it should be like:
0:07, 0:08, 0:09, 0:10, 0:11
and the total time of the audio file is displayed like: 273.298866
But it should be:
4:13
var duration = document.getElementById('fullDuration');
var currentTime = document.getElementById('currentTime');
duration.innerHTML = mytrack.duration;
mytrack.addEventListener("loadedmetadata",function(){
var minutes = parseInt(mytrack.duration / 60);
var seconds = parseInt(mytrack.duration % 60);
duration.innerHTML = minutes + ':' + seconds;
})
And
function update(){
if(!mytrack.ended){
var playedMinutes = parseInt(mytrack.currentTime/60);
var playedSeconds = parseInt(mytrack.currentTime%60);
currentTime.innerHTML = playedMinutes + ':' + playedSeconds;
var size = parseInt(mytrack.currentTime*barSize/mytrack.duration);
progressBar.style.width = size + "px";
}
else{
currentTime.innerHTML = "0.00";
playButton.style.backgroundImage = 'url(file:///Users/Pier/Desktop/Play%20button.png)';
progressBar.style.width = "0px";
window.clearInterval(updateTime);
}
}
The modern way to do this is with String.padStart, but it doesn't work with IE:
currentTime.textContent = playedMinutes + ':' + playedSeconds.toString().padStart(2, '0');

Getting different values from a span

I want to create a website with multiple countdowns activated by a click, some of them have different time, others the same. When one finish I need to return it to his original countdown value, so you will be able to click it again.
I have the times (in seconds) inside a span .time, and that's how I get the time for the countdowns, however I don't know how to save the original time, so when one is clicked I get as "original time" always the first span .time.
Here is my code: http://jsfiddle.net/arglab/m19aojmu/16/
Javascript
function timer(selector) {
var description = ["seconds","hour"]
var self = $(selector);
var sec = parseInt(self.find('span.timeout').text());
console.log(sec)
order++;
var actualTime = $('span.timeout').html();
console.log("Original time " + actualTime)
self.addClass('selec').css('order',order+'');
var interval = setInterval(function() {
sec--;
console.log(sec)
if (sec >= 0) {
var hours = Math.floor(sec / 3600);
var min = Math.floor((sec - (hours*3600)) / 60);
var seconds = Math.floor(sec % 60);
var value = seconds;
if(min > 0) {
if(min == 1) {
value = " minute " + value;
} else {
value = " minutes " + value;
}
value = min + value;
}
if(hours > 0) {
if(hours == 1) {
value = " hour " + value;
} else {
value = " hours " + value;
}
value = hours + value;
}
self.find('span.timeout').text(value);
self.find('span.timeout').text(value);
} else if($(this).find('span').text() <= 0) {
console.log(sec)
var text = self.find('span.timeout').text(actualTime);
console.log(actualTime)
clearInterval(interval);
}
$('.element').each(function(){
if($(this).find('span').text() == 0){
$(this).removeClass('selec');
$(this).css('order','0');
}
});
}, 1000);
}
var order = 1;
$("body").on('click', '.element', function() {
timer(this);
});
HTML
<div id="container">
<div class="element" id="el1"><b>element 1</b> <span class="timeout">1000</span> seconds (1000)</div>
<div class="element" id="el2"><b>element 2</b> <span class="timeout">5</span> seconds (5)</div>
<div class="element" id="el3"><b>element 3</b> <span class="timeout">10</span> seconds (10)</div>
<div class="element" id="el4"><b>element 4</b> <span class="timeout">15</span> seconds (15)</div>
<div class="element" id="el5"><b>element 5</b> <span class="timeout">10</span> seconds (10)</div>
</div>
As you can see, if you click a 10 seconds countdown, when it finish his time isn't 10 seconds (as it should be) but, in this case, 1000 (first span .time)
What can I do? Thanks
You need to use self in your timer function.
Find the comments in the below code,
function timer(selector) {
var description = ["seconds", "hour"]
var self = $(selector);
var sec = parseInt(self.find('span.timeout').text());
console.log(sec)
order++;
var actualTime = self.find('span.timeout').html(); // use self.find here
console.log("Original time " + actualTime)
self.addClass('selec').css('order', order + '');
var interval = setInterval(function () {
sec--;
console.log(sec)
if (sec >= 0) {
var hours = Math.floor(sec / 3600);
var min = Math.floor((sec - (hours * 3600)) / 60);
var seconds = Math.floor(sec % 60);
var value = seconds;
if (min > 0) {
if (min == 1) {
value = " minute " + value;
} else {
value = " minutes " + value;
}
value = min + value;
}
if (hours > 0) {
if (hours == 1) {
value = " hour " + value;
} else {
value = " hours " + value;
}
value = hours + value;
}
self.find('span.timeout').text(value);
// remove the below redundant line
//self.find('span.timeout').text(value);
} else if (self.find('span').text() <= 0) { //use self not this
console.log(sec);
var text = self.find('span.timeout').text(actualTime);
console.log(actualTime)
clearInterval(interval);
}
$('.element').each(function () {
if ($(this).find('span').text() == 0) {
$(this).removeClass('selec');
$(this).css('order', '0');
}
});
}, 1000);
}
Live Demo
When registereing your onclick handler, you should pass another object to the timer function:
$("body").on('click', '.element', function(eve) {
timer(eve.target);
});

Timer to be displayed on a webpage

I want to add a count up timer to my webpage, as in, a label that contains 0:00:00 should start displaying 0:00:01 and so on until the stop button is clicked.
Is there a simple javascript/jquery solution to this?
<html>
<head>
<title>Home</title>
<script src="jquery-1.11.1.js">
</script>
<script>
$(document).ready(function(){
$("p").click(function(){
//psst. psst.
});
});
</script>
</head>
<body>
<form>
<table>
<tr>
<td><input type="text" id="project" placeholder="project"></td>
<td><p id="timer">0:00:00<p></td>
</tr>
</table>
</form>
</body>
</html>
I tried something in Vanilla JS HERE
var seconds=0, minutes=0, hours=0;
var counter;
var stop,start;
var counting = false;
window.onload = function () {
counter = document.getElementById('counter');
stop = document.getElementById('stop');
stop.onclick = function () {
counting = false;
}
start = document.getElementById('start');
start.onclick = function() {
counting = true;
timer();
}
counting = true;
timer();
}
function timer() {
if (seconds >= 60) {
minutes++;
seconds = 0;
}
if (minutes >= 60) {
hours++;
minutes = 0;
}
counter.innerHTML = hours + ":" + minutes + ":" + seconds;
if (counting) {
seconds++;
setTimeout(timer, 1000);
}
}
If you need more info leave a comment..
time.js
function time(id)
{
date = new Date;
h = date.getHours();
if(h<10)
{
h = "0"+h;
}
m = date.getMinutes();
if(m<10)
{
m = "0"+m;
}
s = date.getSeconds();
if(s<10)
{
s = "0"+s;
}
result = h+':'+m+':'+s;
document.getElementById(id).innerHTML = result;
// "setTimeout" call function "time" every 1 second (1000 milliseconds)
setTimeout('time("'+id+'");','1000');
return true;
}
HTML
<html>
<head>
<title>Time in Javascript</title>
<script type="text/javascript" src="time.js"></script>
</head>
<body>
<span id="time"></span>
<script type="text/javascript">window.onload = time('time');</script>
</body>
</html>
Try this way
Use https://github.com/jchavannes/jquery-timer
Include this files in head
<script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript">
<script src="http://jchavannes.com/include/scripts/3p/jquery.timer.js" type="text/javascript">
Script
var Example1 = new (function() {
var $stopwatch, // Stopwatch element on the page
incrementTime = 70, // Timer speed in milliseconds
currentTime = 0, // Current time in hundredths of a second
updateTimer = function() {
$stopwatch.html(formatTime(currentTime));
currentTime += incrementTime / 10;
},
init = function() {
$stopwatch = $('#stopwatch');
Example1.Timer = $.timer(updateTimer, incrementTime, true);
};
this.resetStopwatch = function() {
currentTime = 0;
this.Timer.stop().once();
};
$(init);
});
function formatTime(time) {
var min = parseInt(time / 6000),
sec = parseInt(time / 100) - (min * 60),
hundredths = pad(time - (sec * 100) - (min * 6000), 2);
return (min > 0 ? pad(min, 2) : "00") + ":" + pad(sec, 2) + ":" + hundredths;
}
function pad(number, length) {
var str = '' + number;
while (str.length < length) {str = '0' + str;}
return str;
}
Example1();
DEMO
By using setInterval and Date
You can use button to stop and start timer.
var d = new Date();
d.setHours(0,0,0,0);
setInterval((function(){
return function(){
d.setSeconds(d.getSeconds()+1);
var t = d.toLocaleTimeString("en-US", {hour12: false});
document.getElementById("demo").innerHTML = t;
}
})(), 1000);
Fiddle Demo
Please try this fiddle for your solution.
JS.
var hour = 0;
var min = 0;
var second = 0;
var i=setInterval(function(){
second++;
if(second > 59){
second = 0;
min++;
if(min>59){
hour++;
min = 0;
}
}
var timer_time = (hour > 9 ? hour : '0'+hour)+':'+(min > 9 ? min : '0'+min)+':'+(second > 9 ? second : '0'+second);
$('#timer').html(timer_time);
}, 1000);
$('#stop_timer').click(function(){
clearInterval(i);
});
HTML
<p id='timer'>00:00:00</p>
<button id='stop_timer'>Stop Timer</button>
Thanks
Use timing events like documented at http://www.w3schools.com/js/js_timing.asp.

Categories

Resources