2

I'm new to coding so please go easy on me..

I'm creating base apps so I can get some experience with JavaScript, one of them is a countdown timer involving an input that you input a date/time into and the idea is to initiate a countdown from getTime - inputTime.

I've tried implementing a 'change' event listener to change the textContent.

var timeInput = document.getElementById("timeInput");
var timeCounter = document.getElementById("timeCounter");
var deadline = new Date('dec 31, 2020 15:37:25').getTime();
// var deadline = document.getElementsById("timeInput").getTime();

var x = setInterval(function() {
  var now = new Date().getTime();
  var t = deadline - now;
  var days = Math.floor(t / (1000 * 60 * 60 * 24));
  var hours = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  var minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60));
  var seconds = Math.floor((t % (1000 * 60)) / 1000);

  document.getElementById("timeCounter").innerHTML = days + "d " +
    hours + "h " + minutes + "m " + seconds + "s ";
  if (t < 0) {
    clearInterval(x);
    document.getElementById("timeCounter").innerHTML = "EXPIRED" + " Enter a new date.";
  }
}, 1000);

timeInput.addEventListener("change", function() {
  timeCounter.textContent = t.textContent;
})

The page counts down from 428days regardless of changing the date input.

adiga
  • 34,372
  • 9
  • 61
  • 83

1 Answers1

1

In your change handler, set deadline to the getTime() value of a new DateTime object based on the timeInput value:

(e.g. paste 2019-12-31 18:00:00 into the input and remove the focus from it, and the countdown should start at 57 days)

var timeInput = document.getElementById("timeInput");
var timeCounter = document.getElementById("timeCounter");
var deadline = new Date('dec 31, ' + (new Date().getFullYear()) + ' 23:59:59').getTime();
// var deadline = document.getElementsById("timeInput").getTime();

var x = setInterval(function() {

  var now = new Date().getTime();
  var t = deadline - now;
  var days = Math.floor(t / (1000 * 60 * 60 * 24));
  var hours = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  var minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60));
  var seconds = Math.floor((t % (1000 * 60)) / 1000);
  timeCounter.innerHTML = days + "d " +
    hours + "h " + minutes + "m " + seconds + "s ";
  if (t < 0) {
    clearInterval(x);
    timeCounter.innerHTML = "EXPIRED" + "Enter a new date.";
  }
}, 1000);

timeInput.addEventListener("change", function() {
  deadline = new Date(timeInput.value).getTime();
})
<input type="text" id="timeInput" />
<div id="timeCounter"></div>

The issue with your code was that deadline was never updated, and also the variable t is a local variable, only available in the callback function you passed to setInterval.

You can further do some optimization. As you already have the timeCounter reference, you don't have to use document.getElementById("timeCounter") om your callback function, just use the reference instead.

Constantin Groß
  • 10,719
  • 4
  • 24
  • 50
  • 1
    re `new Date(timeInput.value)`, see [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG Nov 05 '19 at 02:17
  • Good point! This might also help: https://stackoverflow.com/questions/23641525/javascript-date-object-from-input-type-date/23641753#23641753 Using a library like `momentjs` might also be an alternative to handling date/time related issues. – Constantin Groß Nov 05 '19 at 05:51
  • Moment (or any parser) can only reliably parse a string if the format is known. If the format is known, then a simple parser is only a few lines of code. So importing a large library simply to parse a single format is somewhat extravagant. – RobG Nov 05 '19 at 07:17
  • How we can set the timezone? – Shankar S Bavan Jul 19 '21 at 08:05
  • 1
    @ShankarSBavan You can add a specific time zone like this: 2021-07-31 18:00:00 +02:00 – Constantin Groß Jul 19 '21 at 09:31