Im trying to write a program where the user enters their birthday and a countdown timer appears and counts down the months days hours and seconds until their birthday. Right now it is not not working and any help would be great! Thanks!
<body>
<script>
var end = new Date();
document.getElementById("myDate").value = end;
var _second = 1000;
var _minute = _second * 60;
var _hour = _minute * 60;
var _day = _hour * 24;
var _month = _day * 30;
var timer;
function showRemaining() {
var now = new Date();
var distance = end - now;
if (distance < 0) {
clearInterval(timer);
document.getElementById('countdown').innerHTML = 'EXPIRED!';
return;
}
var months = Math.floor(distance / _month);
var days = Math.floor((distance % _month) / _day);
var hours = Math.floor((distance % _day) / _hour);
var minutes = Math.floor((distance % _hour) / _minute);
var seconds = Math.floor((distance % _minute) / _second);
document.getElementById('countdown').innerHTML = months + 'months ';
document.getElementById('countdown').innerHTML += days + 'days ';
document.getElementById('countdown').innerHTML += hours + 'hrs ';
document.getElementById('countdown').innerHTML += minutes + 'mins ';
document.getElementById('countdown').innerHTML += seconds + 'secs';
}
timer = setInterval(showRemaining, 1000);
</script>
Enter your birthday:
<br>
<input type="date" id="myDate">
<br>
<br>
<input type="button" onclick="showRemaining()" value="Enter">
<div id="countdown"></div>
</body>
There are a number of issues with your code as identified in other answers, I'll paraphrase:
The script runs before the elements exist in the DOM, so attempts to reference them return null and you'll get errors attempting to set its properties.
end is set as the page loads, so it's always in the past in respect to when the function runs, so end - now
is either
zero (probably initially) or negative (more than 1 millisecond after assigning to end).
The button will allow multiple instance of setInterval to be running, so you'll get some pretty confusing results since they're all trying to set the value of countdown
The calculation is flawed as there aren't exactly 30 days in every month, nor 24 hours in every day if the host observes daylight saving. Fixing that isn't hard, but I'm not going to fix it here.
Don't use input type Date, support is patchy. You can test for support and handle cases where it isn't, but it's all a bit much for this exercise.
So, don't start the timer until the button is pressed (or some other event after the page is loaded), stop any timer that is currently running and reset end at the same time.
Note that setInterval will drift as it doesn't run at exactly every second, so every now and then it will skip two seconds. Also, invalid date input should be dealt with. Both can be fixed, but out of scope here. ;-)
// Don't set the value for end until the button is pressed.
var end; // = new Date();
// document.getElementById("myDate").value = end;
// Also need a global timer reference so it can be cancelled when required
var timer;
// Since listener is attached by addEventListener, event will only be passed
// if the call comes from the button
function showRemaining(event) {
// Function to cancel the timer
function stopTimer(){
if (timer) {
clearInterval(timer);
end = timer = null;
}
}
// Keep these local
var _second = 1000;
var _minute = _second * 60;
var _hour = _minute * 60;
var _day = _hour * 24;
var _month = _day * 30;
// If click came from the button or timer isn't set, restart the timer
if (event || !timer) {
stopTimer();
timer = setInterval(showRemaining, 1000);
}
// Get the current date
var now = new Date();
// Get the value of countdown and parse it, see parsing function
// If end isn't set, set it
if (!end) end = parseDateDMY(document.getElementById("myDate").value);
var distance = end - now;
// If gone past end, stop the timer
if (distance < 0) {
stopTimer();
document.getElementById('countdown').innerHTML = 'EXPIRED!';
} else {
var months = Math.floor(distance / _month);
var days = Math.floor((distance % _month) / _day);
var hours = Math.floor((distance % _day) / _hour);
var minutes = Math.floor((distance % _hour) / _minute);
var seconds = Math.floor((distance % _minute) / _second);
// Write the time remaining directly to the element
document.getElementById('countdown').innerHTML = months + 'months ' +
days + 'days ' +
hours + 'hrs ' +
minutes + 'mins ' +
seconds + 'secs';
}
}
// No need to do this, wait for button click
// timer = setInterval(showRemaining, 1000);
// Parse date string in format d/m/y
function parseDateDMY(s) {
var b = s.split(/\D/);
var d = new Date(b[2], --b[1], b[0]);
return d && d.getMonth() == b[1]? d : new Date(NaN);
}
// Add listener to button
window.onload = function() {
document.getElementById('startButton').addEventListener('click',showRemaining,false);
}
Enter your birthday:<br>
<input type="text" id="myDate" value="21/6/2016">d/m/y<br>
<input type="button" id="startButton" value="Start counting"><br>
<div id="countdown"></div>