It would be great if someone could point me in the right direction for a school project I am working on. Below you see a super simple timer I made with the help of a tutorial from a youtuber called Web Dev. The example had the New Years eve hardcoded into the script. But I would like to take this one step further and ask the user to enter their special date - so as to make the timer count down to their birthday for example.
So far I have managed to make the counter count down from a given date, not just a hard coded date, and I have managed to create entry forms for user generated data. But once I tried to combine the two something went wrong. I am guessing I need to enter the user generated numbers into one of the functions, not just list them on top as let, var and const?
Oh, and I should ideally figure out a way to make the entry form disappear as soon as the user clicks on the 'enter' button.
For my previous StackOverflow question someone very kindly coded out the entire answer for me. But since this is very much a learning process I would be perfectly happy with a few hints and pointers in the right direction.
let userYear = userYearEntered;
let userMonth = userMonthEntered;
let userDay = userDayEntered;
const userDate = new Date(userYear, userMonth, userDay, 0, 0, 0);
const userOccasion = 'I need to present this project';
function enterSpecialDate() {
var userYearEntered = document.getElementById('userYear').value;
console.log(userYearEntered);
var userMonthEntered = document.getElementById('userMonth').value;
console.log(userMonthEntered);
var userDayEntered = document.getElementById('userDay').value;
console.log(userDayEntered);
}
/*create countdown timer using substraction*/
function updateCountdowntime() {
const currentTime = new Date();
const diff = userDate - currentTime;
console.log(diff);
/* we've been given the difference in milliseconds, so some division is needed */
const d = Math.floor(diff / 1000 / 60 / 60 / 24);
const h = Math.floor(diff / 1000 / 60 / 60) % 24;
const m = Math.floor(diff / 1000 / 60) % 60;
const s = Math.floor(diff / 1000) % 60;
/* send values back into HTML document */
document.getElementById('days').innerHTML = d;
document.getElementById('hours').innerHTML = h;
document.getElementById('minutes').innerHTML = m;
document.getElementById('seconds').innerHTML = s;
document.getElementById('userOccasion').innerHTML = userOccasion;
}
setInterval(updateCountdowntime, 1000);
* {
box-sizing: border-box;
}
body {
background-color: rgb(44, 48, 48);
font-family: sans-serif;
color: rgb(239, 239, 239);
font-size: 3em;
font-weight: 300;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
div {
margin-top: 1vh;
}
label {
font-size: 0.4em;
}
<div>
<label for="userYear">year</label>
<input id="userYear" type="number" value="" placeholder="e.g. 2021">
<label for="userMonth">month</label>
<input id="userMonth" type="number" value="" placeholder="e.g. 8">
<label for="userDay">day</label>
<input id="userDay" type="number" value="" placeholder="17">
<button onclick="enterSpecialDate()">Enter</button>
</div>
<div>
<p>there are</p>
<div class="time">
<span id="days"></span>
<span>days</span>
</div>
<div class="time">
<span id="hours"></span>
<span>hours</span>
</div>
<div class="time">
<span id="minutes"></span>
<span>minutes</span>
</div>
<div class="time">
<span id="seconds"></span>
<span>seconds</span>
</div>
<p>until <span id="userOccasion"></span></p>
</div>
Here's a solution using a date input, which is more semantic, accessible and more comfortable to use for the end user.
It's using inline styles to switch between the form and the countdown, but the same could be achieved using classList.toggle() and a class for showing or hiding the specific view.
You should also implement some form of error handling (e.g. right now it simply does nothing when clicking the button while not having set a date, and it also supports dates in the past, resulting in negative numbers).
A note on setInterval(): It's not reliable/exact enough and may result in seconds being skipped or changing too quickly. For more background about this and a reliable solution I recommend the video "JavaScript counters the hard way - HTTP 203
" on YouTube. The solution is also available as a reusable code snippet in this gist.
It should now be rather simple for you to implement the additional input for the occasion text.
let userDate = null;
const userOccasion = 'I need to present this project';
const userDateInput = document.getElementById('user-date');
const formView = document.getElementById('form-view');
const counterView = document.getElementById('counter-view');
function enterSpecialDate() {
userDate = userDateInput.valueAsDate;
if (userDate) {
// fire the function once, so we start with filled in numbers right away
updateCountdowntime();
// see the note on setInterval() in the answer
setInterval(updateCountdowntime, 1000);
// switch between the form and the counter view
formView.style.display = 'none';
counterView.style.display = 'block';
}
}
/*create countdown timer using substraction*/
function updateCountdowntime() {
const currentTime = new Date();
const diff = userDate - currentTime;
/* we've been given the difference in milliseconds, so some division is needed */
const d = Math.floor(diff / 1000 / 60 / 60 / 24);
const h = Math.floor(diff / 1000 / 60 / 60) % 24;
const m = Math.floor(diff / 1000 / 60) % 60;
const s = Math.floor(diff / 1000) % 60;
/* send values back into HTML document */
document.getElementById('days').innerHTML = d;
document.getElementById('hours').innerHTML = h;
document.getElementById('minutes').innerHTML = m;
document.getElementById('seconds').innerHTML = s;
document.getElementById('userOccasion').innerHTML = userOccasion;
}
* {
box-sizing: border-box;
}
body {
background-color: rgb(44, 48, 48);
font-family: sans-serif;
color: rgb(239, 239, 239);
font-size: 2em;
font-weight: 300;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
div {
margin-top: 1vh;
}
<div id="form-view">
<input type="date" id="user-date">
<button onclick="enterSpecialDate()">Enter</button>
</div>
<div id="counter-view" style="display: none;">
<p>there are</p>
<div class="time">
<span id="days"></span>
<span>days</span>
</div>
<div class="time">
<span id="hours"></span>
<span>hours</span>
</div>
<div class="time">
<span id="minutes"></span>
<span>minutes</span>
</div>
<div class="time">
<span id="seconds"></span>
<span>seconds</span>
</div>
<p>until <span id="userOccasion"></span></p>
</div>
You should be able to do this with a couple of simple prompts or text input fields.
For example:
Ask the user to put in a month, then a day and then a year. You save these inputs as separate variables. Then you use the const newYearTime but instead of using the hardcoded date you use the variables as date.
Now you have const newYearTime = new Date('january' ,1,current year etc...)
With the prompts you could do:
let year = number(prompt: enter year)
let day = number(prompt: enter day)
let month = prompt: enter month
And then you just change the const newYearTime to
Const newYearTime = new Date(month, day, year)
My code isn't correct i know. I am not at my pc so i don't have my editor to write it like it should be but i think you get what I mean.
I am pretty new to javascript too but i try to help if i think i know how to do it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With