Creating a reverse progress bar in HTML and Javascript that incorporates a countdown date

I'm struggling to find a way to create a progress bar that empties as it gets closer to the countdown date.

I came across two different examples that I think could be merged, but I'm not sure how to do it:
Countdown - https://www.jqueryscript.net/time-clock/Minimal-jQuery-Any-Date-Countdown-Timer-Plugin-countdown.html (1st example, SIMPLE TEXT COUNTDOWN)
Progress bar - https://jsfiddle.net/zessx/4PKEB/1/:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {    
function progress(timeleft, timetotal, $element) {
var progressBarWidth = (timeleft / timetotal) * $element.width();
    $element.find('div').animate({ width: progressBarWidth }, timeleft == timetotal ? 0 : 1000, 'linear').html(timeleft + " seconds to go");
    if(timeleft > 0) {
        setTimeout(function() {
            progress(timeleft - 1, timetotal, $element);
        }, 1000);
    }
};
progress(20, 20, $('#progressBar'));
});
</script>

<style>
#progressBar {
    width: 90%;
    margin: 10px auto;
    height: 22px;
    background-color: #0A5F44;
}

#progressBar div {
    height: 100%;
    text-align: right;
    padding: 0;
    line-height: 22px; 
    width: 0;
    background-color: #CBEA00;
    box-sizing: border-box;
}
</style>

<div id="progressBar">
    <div></div>
</div>

UPDATE QUESTION
Let me explain further what I am looking for.
I want to combine the code from both links to achieve something like this:
https://i.sstatic.net/tEUzG.png
Essentially, I want the countdown text (circled in blue) to correspond with the decreasing color (circled in red) in the progress bar.
In short, I need a progress bar with text showing the countdown of days, hours, minutes, and seconds until a specific date rather than for a set duration.

My complete HTML is:

<!doctype html>
<html>
...

Any assistance would be greatly appreciated!

Answer №1

Although it may be overdue, I wanted to provide this information in case anyone else requires it, complete with the starting and ending dates.

Inspired by Lowell Ed Llames's response:

 $(document).ready(function() {
    function progress(timeleft, timetotal, $element) {

        let days = parseInt(timeleft / 86400);
        let hoursLeft = parseInt(timeleft - days * 86400);
        let hours = parseInt(hoursLeft / 3600);
        let minutesLeft = parseInt(hoursLeft - hours * 3600);
        let minutes = parseInt(minutesLeft / 60);
        let seconds = parseInt(timeleft % 60);

        let progressBarWidth = timeleft / timetotal * $element.width();

        $element
        .find("div")
        .css('width', progressBarWidth );
        $('.timeleft').html(
         `${days} days, ${hours} hours, ${minutes} minutes, ${seconds} seconds`);
        if (timeleft > 0)
        setTimeout(() => progress(timeleft - 1, timetotal, $element), 1000);
    }

    // Starting Date
    let dateStart = new Date('2021-03-10');

    // Ending Date
    let dateEnd   = new Date('2021-03-20');

    // Current Date
    let dateNow   = new Date('2021-03-17');

    let timetotal = (dateEnd.getTime() / 1000) - (dateStart.getTime() / 1000);
    let timeleft  = (dateEnd.getTime() / 1000) - (dateNow.getTime() / 1000);

    progress(timeleft, timetotal, $("#progressBar"));
 });
#progressBar {
  width: 90%;
  margin: 10px auto;
  height: 22px;
  background-color: #ececee;
  border-radius: 15px;
  overflow: hidden;
}
#progressBar div {
   height: 100%;
   text-align: right;
   padding: 0;    /* remove padding */
   line-height: 22px;
   width: 0;
   background-color: #7ac843;
   box-sizing: border-box;
   overflow: visible;
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://www.jqueryscript.net/demo/Minimal-jQuery-Any-Date-Countdown-Timer-Plugin-countdown/dest/jquery.countdown.Javascript"></script>
  
<p>Time left: <span class="timeleft"></span></p>
<div id="progressBar">
    <div></div>
</div>

Answer №2

Let me provide a solution in the form of an answer rather than just a comment:

Instead of calculating upwards, try subtracting the progress from the total:

var totalTime = 100;
var currentTime = 15;
var timeRemaining = totalTime - currentTime;
var progressPCT = (currentTime / totalTime ) * 100;
var remaningProgressPCT = 100 - progressPCT; 
console.log("Time Remaining: ", timeRemaining);
console.log("Progress Bar Fill: ", remainingProgressPCT);

After that, use the variable remaningProgressPCT as the progress on your bar.

Answer №3

Begin by examining your script

function progress(timeleft, timetotal, $element) {
  var progressBarWidth = (timeleft / timetotal) * $element.width(); //<-- improve the formula

 // add your code here
};

Next, apply the styles:

#progressBar div {
  height: 100%;
  text-align: right;
  padding: 0;    /* eliminate padding */
  line-height: 22px;
  width: 0;
  background-color: #CBEA00;
  box-sizing: border-box;
}

UPDATE

$(document).ready(function() {
  function progress(timeleft, timetotal, $element) {
    let progressBarWidth = timeleft / timetotal * $element.width();

    let days = parseInt(timeleft / 86400);
    let hoursLeft = parseInt(timeleft - days * 86400);
    let hours = parseInt(hoursLeft / 3600);
    let minutesLeft = parseInt(hoursLeft - hours * 3600);
    let minutes = parseInt(minutesLeft / 60);
    let seconds = parseInt(timeleft % 60);

    $element
      .find("div")
      .animate(
        { width: progressBarWidth },
        timeleft == timetotal ? 0 : 1000,
        "linear"
      )
      .html(
        `${days} days, ${hours} hours, ${minutes} minutes, ${seconds} seconds`
      );
    if (timeleft > 0)
      setTimeout(() => progress(timeleft - 1, timetotal, $element), 1000);
  }
  progress(60, 60, $("#progressBar"));
});
body {
    font: 13px/1.4 'Helvetica Neue', 'Helvetica','Arial', sans-serif;
    color: #333;
}
.container {
    width: 520px;
    margin: auto;
}
h1 {
    border-bottom: 1px solid #d9d9d9;
}
h2{
    position: relative; 
    font-size: 16px;
    font-weight: normal;
    text-transform: uppercase;
}
h2:before{
    content: '\2192';
    position: absolute;
    left: -20px;
    font-size: 0.9em;
}
a {
    color: #be2221;
    text-decoration: none;
}

.simple {
    font-size: 20px;
    background: #27ae60;
    padding: 0.5em 0.7em;
    color: #ecf0f1;
    margin-bottom: 50px;
    -webkit-transition: background 0.5s ease-out;
    transition: background 0.5s ease-out;
}
.simple {
    margin-bottom: 50px;
}
.simple div {
    display: inline-block;
    margin-left: 10px;
    font-size: 30px;
    font-weight: 100;
    line-height: 1;
    text-align: right;
}
/* IE7 inline-block hack */
*+html .simple div {
    display: inline;
    zoom: 1;
}
.simple div:first-child {
    margin-left: 0;
}
.simple div span {
    display: block;
    border-top: 1px solid #cecece;
    padding-top: 3px;
    font-size: 12px;
    font-weight: normal;
    text-transform: uppercase;
    text-align: left;
}

#progressBar {
    width: 90%;
    margin: 10px auto;
    height: 22px;
    background-color: #fff;
    border:1px solid #ddd;
}
#progressBar div {
  height: 100%;
  text-align: right;
  padding: 0;    /* remove padding */
  line-height: 22px;
  width: 0;
  background-color: #CBEA00;
  box-sizing: border-box;
  overflow: visible;
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.jqueryscript.net/demo/Minimal-jQuery-Any-Date-Countdown-Timer-Plugin-countdown/dest/jquery.countdown.js"></script>

  <div id="progressBar">
      <div></div>
  </div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for accessing nested documents from Firebase in React.js

Here is a snippet of code from my React project: import React, { useState } from "react"; import { db } from "../firebase"; import { collection, Firestore, getDocs } from "firebase/firestore"; function Document() { const ...

Problems with select box rendering in Internet Explorer with Materialize CSS

When using materializecss select box in Internet Explorer 9 or higher, scrolling with the mouse button is not working. You must click on the scroll bar inside the select box for it to scroll. This issue does not occur in other browsers. I have attached a s ...

Loss of data in the local storage when the page is reloaded

click here to see image I have managed to save data to local Storage successfully, but it keeps disappearing when I reload the page. Can someone guide me on how to handle this issue? I am new to this and would greatly appreciate any help. Thank you. https ...

Sequelize throwing Javascript heap out of memory error when inserting large files into database

I have successfully converted an excel file to MySQL on my local machine. However, when I try to do the same with larger files on a container limited to 2048MB of memory, it doesn't work. I attempted to increase the memory limit using node --max-old-s ...

Using Vue: Incorporating and extracting JSON data with JavaScript

I need to import the following JSON from a different component because it includes require and Math. I am having trouble saving it in JSON file format. let test = [ { name:"A", imgSrc: require('@/assets/img/A.png'), ...

Ways to emphasize a particular <li> element?

Currently, I am delving into the world of React and facing a challenge. I have been trying to solve the issue below: When fetching some JSON data, it appears in this format: [ { "answerOptions": [ "Answer A", "Answer B", ...

issues related to implementing search functionality with react-redux

Just starting out with my first react-redux project which is a list of courses, but I have hit a roadblock with redux. I am trying to implement a search functionality based on this answer, and while I can see the action in redux-devtools, it's not ref ...

Discovering image file extensions in JavaScript using regular expressions

Can anyone provide me with a javascript regular expression to validate image file extensions? ...

JavaScript method that accepts two functions as arguments

What is the proper syntax for passing two or more functions to a method, like in this example setInterval("javascript function",milliseconds); is the following correct? setInterval("pushmarkers();clearOverlays();loadmarkers();",5000); ...

Best practices for managing an array of buttons and handling click events in ReactJs

While working on my react class component, I encountered an issue. The alert popup keeps appearing constantly without any button click as soon as the component renders. onHandleOnClick(data, e) { console.log(data); alert("got it" + data); } rend ...

Tips on setting up a self-start event or alert in ASP.NET

I am trying to figure out how to trigger an alert for the user once a specific time has been reached. The challenge is that it cannot be initiated by a button click event or any other action. I want the alert to be displayed even if the user is on a diff ...

What advantages do binary shifts offer in enums?

What do you think about this code snippet? /** * Bitmask of states */ export const enum ViewState { FirstCheck = 1 << 0, // result is 1 ChecksEnabled = 1 << 1, // result is 2 Errored = 1 << 2, // result is 4 ...

Creating animated reactions in discord.js is a goal of mine, however, I am encountering an issue that needs to

Last year, I asked this question and received helpful answers. However, there is still a problem that I couldn't figure out. Since I am unable to comment on the previous answers, I have decided to add a new question client.on('message', mess ...

How can I find the URL of a webpage that is not showing up in the search bar? Utilize Google Instant

I'm currently working on an extension and I've encountered a challenge... I'm trying to figure out how to extract the URLs from a Google instant search page. The browser's URL bar doesn't seem to update instantly, so I'm unsur ...

I'm looking to add CSS transitions, like fade-ins, to a list of items in React in a way that the animations occur one after the other upon rendering. How can this be achieved?

I've scoured the depths of Stack Overflow and combed through countless pages on the internet in search of an answer to my query, but alas, I have not found a solution. So, my apologies if this question is a duplicate. Here's my conundrum: https ...

Incorporate distinct items into an array using reactjs

I'm facing an issue where clicking on a certain element multiple times adds it to my array multiple times. I need help in figuring out how to add only unique elements to the array. Can anyone offer some guidance? Thank you in advance. const handleCli ...

Utilizing HTML and JavaScript to dynamically switch stylesheets based on the width of

When it comes to using stylesheets for mobile and non-mobile devices, there is a need for different approaches. The idea of comparing browser height and width in JavaScript seems like a good one, but the implementation may not always work as expected. ...

How can a controller configure an AngularJS provider by passing options?

How can I pass configuration options to a provider from a controller? Below is an example of how to pass options/configurations to a provider from the controller: provider.js file: app.provider('contactProvider', function() { this.name ...

Issues with AJAX formData functionality

I'm having difficulties with the formData in my Ajax calls. I have searched extensively for solutions and tried various approaches, including using getElementById, but nothing seems to work. The form in question has an id of add-lang-form: <form ...

PHP Calculator - Displaying results in both the webpage and an Ajax popup for enhanced user experience

UPDATE - the issue was resolved by incorporating $('.popup-with-form').magnificPopup('open'); into the StateChanged function in the JavaScript. Many thanks to @Bollis for the assistance. The Initial Query: I have a basic calculator lo ...