How to Create Javascript Countdown Timer With User Input
First of all, load the following assets into the head tag of your HTML document.
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"> <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Ubuntu'>
Create the HTML structure for the countdown timer as follows:
<div class="wrapper">
<div id="setup" class="card">
<div class="header">
<h1>The Final Countdown</h1>
<div class="button-group">
<button type="button" class="button-start" id="go">Generate Timer</button>
<button type="button" class="button-cancel" id="cancel">Clear Fields</button>
</div>
</div>
<h2>Event Info</h2>
<div class="fields">
<div class="input-group">
<label>Event Name</label>
<input type="text" name="event-name" autofocus />
</div>
<div class="input-group">
<label>Complete Message</label>
<input type="text" name="event-complete-msg"/>
</div>
<div class="input-group">
<label>Organizer</label>
<input type="text" name="event-organizer" />
</div>
</div>
<h2>Event Date/Time</h2>
<div class="fields">
<div class="input-group">
<label>Day</label>
<select name="day">
</select>
</div>
<div class="input-group">
<label>Month</label>
<select name="month">
</select>
</div>
<div class="input-group">
<label>Year</label>
<select name="year">
</select>
</div>
<div class="input-group">
<label>Time (Hour)</label>
<select name="hour">
</select>
</div>
<div class="input-group">
<label>Time (Minute)</label>
<select name="minute">
</select>
</div>
<div class="input-group">
<label>Time (Seconds)</label>
<select name="second">
</select>
</div>
</div>
</div>
<div id="countdown" class="card hidden">
<div class="header">
<h1>Countdown</h1>
<div class="button-group">
<button type="button" class="button-cancel" id="clear">Clear Timer</button>
</div>
</div>
<div class="countdown-wrapper">
<div class="clock-wrapper">
<div id="clock">loading...</div>
</div>
<div class="event-details">
<div id="event-complete-display" class="hidden"></div>
<div class="event-in-progress" id="event-in-progress">
<div id="event-name-display"></div>
<div id="event-organizer-display"></div>
</div>
</div>
<small>Event Date: <span id="end-date"></span></small>
</div>
</div>
</div>
Style the countdown timer using the following CSS styles:
* {
box-sizing: border-box;
font-family: 'Ubuntu', sans-serif;
}
.wrapper {
display: relative;
overflow: hidden;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
h1, h3 {
font-weight: normal;
margin: 0;
padding: 0;
}
h2 {
background-color: rgba(0,0,255, 0.7);
color: #f5f5f5;
padding: 12px;
/* box-shadow: 4px 6px 6px #ccc; */
margin: 46px 0 16px 0;
}
.countdown-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
min-height: 100%;
text-align: center;
}
.clock-wrapper {
font-size: 1.5em;
}
.event-details {
background-color: #ccc;
width: 100%;
min-height: 200px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 5px 10px 6px -6px #777;
border-radius: 5px;
}
.event-in-progress {
display: flex;
flex-direction: column;
}
.fields {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
.input-group {
display: flex;
flex-direction: column;
width: 30%;
margin-bottom: 16px;
}
.input-group label {
display: block;
font-size: 1.1em;
padding: 3px;
background-color: #333;
color: #f5f5f5;
}
.input-group input {
width: 100%;
max-width: 100%;
border: none;
border-bottom: 1px solid #ccc;
font-size: 2em;
padding: 6px;
color: #333;
transition: border-color 0.3s ease;
}
.input-group input:focus {
outline: none;
border-color: #333;
}
.input-group select {
width: 100%;
height: 100%;
margin-top: 0;
font-size: 2em;
padding: 3px;
border: none;
color: #333;
}
.input-group select:focus {
outline: none;
}
.input-group option {
font-weight: 100;
}
.input-group option:focus {
outline: none;
}
.button-group {
text-align: center;
position: fixed;
top: 5px;
right: 5px;
}
.button-group button {
border: none;
padding: 6px;
color: #f5f5f5;
border-radius: 3px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.button-start {
background-color: rgba(0,0,255, 0.4);
}
.button-start:hover {
background-color: rgba(0,0,255,0.7);
}
.button-cancel {
background-color: rgba(255,0,0,0.4);
}
.button-cancel:hover {
background-color: rgba(255,0,0,0.7);
}
.card {
width: 100%;
height: 100%;
position: absolute;
background-color: #fff;
top: 0;
left: 0;
right: 0;
padding: 12px;
transition: transform 0.5s ease;
}
.hidden {
transform: translateY(-100%);
}
Add the following JavaScript function for its functionality:
//no es6 for now
/*
TODO
1) format timer (large countdown text, nicer date format, add event name, organizer)
2) on complete, show message
3) add complete style options (fireworks, 'meltdown', snake?)
*/
var yearOptions = [];
var currentYear = new Date().getFullYear();
for (var i = currentYear; i <= currentYear + 50; i += 1) {
yearOptions.push({
title: i,
value: i
});
}
var monthOptions = [];
for (var i = 1; i <= 12; i += 1) {
var monthNameMatrix = {
1: 'January', 2: 'February', 3: 'March', 4: 'April', 5: 'May', 6: 'June', 7: 'July', 8: 'August', 9: 'September', 10: 'October', 11: 'November', 12: 'December'
};
monthOptions.push({
title: monthNameMatrix[i],
value: i
});
}
var dayOptions = [];
for (var i = 1; i <= 31; i += 1) {
dayOptions.push({
title: i,
value: i
});
}
var hourOptions = [];
for (var i = 0; i <= 24; i += 1) {
if(i === 0) {
hourOptions.push({ title: 'Midnight', value: i });
} else if(i < 12) {
hourOptions.push({ title: i + 'am', value: i });
} else if(i === 12) {
hourOptions.push({ title: 'Noon', value: i });
} else {
hourOptions.push({ title: i - 12 + 'pm', value: i });
}
}
var timeOptions = [];
for (var i = 0; i <= 59; i += 1) {
timeOptions.push({
title: i,
value: i
});
}
(function() {
'use strict';
//buttons
var start = document.querySelector('#go');
var cancel = document.querySelector('#cancel');
var clear = document.querySelector('#clear');
//main divs (show/hide)
var setupView = document.querySelector('#setup');
var timerView = document.querySelector('#countdown');
//display divs
var eventNameDisplay = document.querySelector('#event-name-display');
var eventOrganizerDisplay = document.querySelector('#event-organizer-display');
var eventCompleteDisplay = document.querySelector('#event-complete-display');
var eventInProgress = document.querySelector('#event-in-progress');
//inputs
var eventName = document.querySelector('[name=event-name]');
var eventCompleteMsg = document.querySelector('[name=event-complete-msg]');
var eventOrganizer = document.querySelector('[name=event-organizer]');
var secondInput = document.querySelector('[name=second]');
var minuteInput = document.querySelector('[name=minute]');
var hourInput = document.querySelector('[name=hour]');
var dayInput = document.querySelector('[name=day]');
var monthInput = document.querySelector('[name=month]');
var yearInput = document.querySelector('[name=year]');
//sharable handlers
var timerHandle, cancelHandler;
function countdownClock() {
var display = document.querySelector('#clock');
var endDateDisplay = document.querySelector('#end-date');
var end = new Date(yearInput.value, (+monthInput.value - 1), dayInput.value, hourInput.value, minuteInput.value, secondInput.value);
function tick() {
var now = new Date();
var remainingMilliseconds = end - now;
if (remainingMilliseconds <= 1000) {
clearInterval(timerHandle);
timerHandle = null;
clock.innerHTML = 'COMPLETE';
eventInProgress.classList.add('hidden');
eventCompleteDisplay.innerHTML = eventCompleteMsg.value;
eventCompleteDisplay.classList.remove('hidden');
return;
}
endDateDisplay.innerHTML = end;
var remainingSeconds = Math.floor(remainingMilliseconds / 1000);
var remainingMinutes = Math.floor(remainingMilliseconds / (1000 * 60));
var remainingHours = Math.floor(remainingMilliseconds / (1000 * 60 * 60));
var remainingDays = Math.floor(remainingMilliseconds / (1000 * 60 * 60 * 24));
var displayHours = remainingHours - (remainingDays * 24);
var finalHours = displayHours > 9 ? displayHours : '0' + displayHours;
var displayMinutes = remainingMinutes - (remainingHours * 60);
var finalMinutes = displayMinutes > 9 ? displayMinutes : '0' + displayMinutes;
var displaySeconds = remainingSeconds - (remainingMinutes * 60);
var finalSeconds = displaySeconds > 9 ? displaySeconds : '0' + displaySeconds;
var dayOrDays = remainingDays === 1 ? 'day' : 'days';
var hourOrHours = displayHours === 1 ? 'hour' : 'hours';
var minuteOrMinutes = displayMinutes === 1 ? 'minute' : 'minutes';
var secondOrSeconds = displaySeconds === 1 ? 'second' : 'seconds';
eventNameDisplay.innerHTML = eventName.value;
eventOrganizerDisplay.innerHTML = `Created By: ${eventOrganizer.value}`;
clock.innerHTML = remainingDays + ' ' + dayOrDays + ' ' + finalHours + ' ' + hourOrHours + ' ' + finalMinutes + ' ' + minuteOrMinutes + ' ' + finalSeconds + ' ' + secondOrSeconds + ' remaining until...';
}
timerHandle = setInterval(tick, 1000);
console.log(yearInput.value);
timerView.classList.remove('hidden');
cancelHandler = clear.addEventListener('click', clearTimer, false);
}
function clearTimer() {
clearInterval(timerHandle);
timerHandle = null;
resetForm();
eventNameDisplay.innerHTML = '';
eventOrganizerDisplay.innerHTML = '';
clear.removeEventListener('click', cancelHandler);
timerView.classList.add('hidden');
eventInProgress.classList.remove('hidden');
eventCompleteDisplay.innerHTML = '';
eventCompleteDisplay.classList.add('hidden');
}
function resetForm() {
eventName.value = '';
eventCompleteMsg.value = '';
eventOrganizer.value = '';
dayInput.value = 1;
monthInput.value = 1;
yearInput.value = currentYear;
hourInput.value = 0;
minuteInput.value = 0;
secondInput.value = 0;
eventName.focus();
}
function setupSelectOptions(selectElement, optionsArray) {
optionsArray.forEach(function(option) {
var o = document.createElement('option');
o.value = option.value;
o.text = option.title;
selectElement.add(o, null);
})
}
setupSelectOptions(dayInput, dayOptions);
setupSelectOptions(monthInput, monthOptions);
setupSelectOptions(yearInput, yearOptions);
setupSelectOptions(hourInput, hourOptions);
setupSelectOptions(minuteInput, timeOptions);
setupSelectOptions(secondInput, timeOptions);
start.addEventListener('click', countdownClock, false);
cancel.addEventListener('click', resetForm, false);
})();
That’s all! hopefully, you have successfully integrated the JavaScript code for the countdown timer with user Input. If you have any questions or suggestions, feel free to comment below.
