JavaScript Countdown Timer With User Input

JavaScript Countdown Timer With User Input
Project: User Input Countdown
Author: Joe Driscoll
Edit Online: View on CodePen
License: MIT
This JavaScript code snippet helps you to create a countdown timer. It shows a timer that can be set for an event by inputting the event name, date, and time. The timer can be started, canceled, and cleared by the buttons on the page. The purpose of the code is to create and display options for year, month, day, hour, and minute for setting the countdown timer. The code also formats and displays the countdown text, end date, event name, and organizer.
Finally, when the timer reaches zero, it shows a message with the text provided by the user in the “event-complete-msg” input. The code uses plain JavaScript and does not use any ECMAScript 6 features.

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.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *