Ways to complete a progress bar up to 100% based on the user's specified time

I'm currently developing a progress bar for a pomodoro timer. The concept is for this bar to reach 100% completion based on the specified time of the pomodoro session. For instance, if the session is set for 30 minutes, the progress bar should be fully filled at the end of the 30 minutes.

let progressBar = document.getElementById("progressBar");
let value = 30
let seconds = 120

let dataValue = progressBar.setAttribute("data-value", `${value}`)

dataAttribute = progressBar.getAttribute('data-value');
console.log(dataAttribute)

let bar = 0

progressBar.style.width = bar;

let id = setInterval(function(){
    bar++;
    progressBar.style.width = bar + "%"
    if (bar >=dataAttribute){
        clearInterval(id)
    }
},1000)
.progress {
    width: 100%;
    background-color: #ddd;
    margin-bottom: 15px;
}

.progress-bar {
    width: 0;
    height: 10px;
    background: #c49b66;
    text-align: center;
    line-height: 30px;
    color: white;
    transition-duration: 5s;
    transition-timing-function: ease;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />

    <!-- Bootstrap CSS -->
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
      integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
      crossorigin="anonymous"
    />

    <link rel="stylesheet" type="text/css" media="screen" href="svg.css" />
    <title>Hello, world!</title>
  </head>
  <body>
    <div class="progress">
      <div class="progress-bar" id="progressBar">progress</div>
    </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script
      src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
      integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
      integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
      integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
      crossorigin="anonymous"
    ></script>
    <script src="svg.js"></script>
  </body>
</html>

The functionality should be such that if a user sets a timer for 30 minutes, the progress bar will move accordingly and once it reaches the 30-minute mark, it should show 100% completion

The intent is to achieve this using vanilla JavaScript instead of jQuery. Thank you for your assistance

Answer №1

It is not advisable to rely on intervals/timeouts for an accurate countdown. Instead, using timestamps to calculate the difference is a more reliable approach. The concept demonstrated here involves utilizing timestamps and simple math to update a progress element.

function setUpProgressBar(selector, startTime, endTime, update) {

  var timer
  var elem = document.querySelector(selector)
  var max = endTime - startTime
  elem.max = max

  var setValue = function() {
    var currentTime = new Date().getTime()
    var elapsed = currentTime - startTime
    if (elapsed >= max) {
      elapsed = max
      window.clearTimeout(timer)
    }
    elem.value = elapsed
    var prec = elapsed/max * 100
    elem.setAttribute("data-label", prec.toFixed(2) + '%')
  }

  setValue()
  timer = window.setInterval(setValue, update)
  return
}

var start1 = new Date()
var end1 = new Date()
end1.setMinutes(end1.getMinutes() + 5);

setUpProgressBar("#pb1", start1.getTime(), end1.getTime(), 100)

var start2 = new Date()
start2.setMinutes(start2.getMinutes() - 20);
var end2 = new Date()
end2.setMinutes(end2.getMinutes() + 5);
setUpProgressBar("#pb2", start2.getTime(), end2.getTime(), 1000)

var start3 = new Date()
start3.setMinutes(start3.getMinutes() - 60);
var end3 = new Date()
end3.setMinutes(end3.getMinutes() + 1);
setUpProgressBar("#pb3", start3.getTime(), end3.getTime(), 100)
progress {
  text-align: center;
  height: 1.5em;
  width: 100%;
  -webkit-appearance: none;
  border: none;
  position:relative;
}
progress:before {
  content: attr(data-label);
  font-size: 0.8em;
  vertical-align: 0;
  position:absolute;
  left:0;
  right:0;
}
<progress id="pb1"></progress>

<progress id="pb2"></progress>

<progress id="pb3"></progress>

Answer №2

Here's a way to achieve a similar effect:

// Suppose you wish for the progress to complete in 10 seconds
let seconds = 10;
let id = setInterval(function(){
    bar++;
    progressBar.style.width = bar + "%"
    if (bar >=dataAttribute){
        clearInterval(id)
    }
}, seconds * 1000 / 100)

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

What is the best way to eliminate a JSON header?

Here is the JSON data I have: { "folder": [ { "$": { "id": "471841542", "name": "Manajemen Pemasaran", "description": "", "user_id": "186868958", "shared": "1", "shared_l ...

Eliminate the excess padding from the Material UI textbox

I've been struggling to eliminate the padding from a textbox, but I'm facing an issue with Material UI. Even after setting padding to 0 for all classes, the padding persists. Could someone provide guidance on how to successfully remove this pad ...

Is the WordPress error message "wp_register_style was improperly called" showing up on

I am facing an issue while trying to incorporate this code into my initial Wordpress template. It seems that the libraries for Bootstrap and my custom styles are not functioning as expected. Here is the code snippet in question. Any insights would be great ...

Arrangement of div elements tailored to fit the size of the viewport

I am working on creating a grid of divs that will cover the entire viewport. To start, I want to have a grid that is 7 divs wide and 10 divs high. Below is the code snippet I've written so far to set the size of the div elements: function adjustHeig ...

Whenever I attempt to connect to Stripe, my code fails to execute properly

My knowledge of Javascript is limited, but I have a basic understanding. I am currently diving into learning about Stripe and testing it in a local environment with a Wordpress install. Following the Stripe documentation, I have successfully installed Node ...

Having trouble with QuickBlox video calling feature on the web?

I have encountered an issue while trying to integrate video chat into my Java web application using QuickBlox. I am utilizing Angular/JavaScript on the frontend. The problem arises when attempting to create a session for a user that I have created in Quic ...

Is it possible to incorporate dynamic variables into the directives of a nested loop? Plus, thoughts on how to properly declare variables in a node.js environment

Question Explanation (Zamka): <----------------------------------------------------------------------------------------------------------> Input Example: 100 500 12 1st Line: represents the left bound (L) 2nd Line: represents the right bound ...

What is the reason behind my button appearing beneath my links in React?

https://i.sstatic.net/Qmm4z.jpg Here is an image showcasing the current header render. The header consists of a HeaderMenu and 3 Links. While the links are functioning properly, the HeaderMenu is causing the links to be positioned below it. The HeaderMenu ...

delete the initial background color assigned to the button

The "ADD TO CART" and "save design" buttons are currently displaying as shown in the image below. I would like to make the "SAVE DESIGN" button look similar to the "ADD TO CART" button, meaning I want to remove the background-color and dot symbol. Code ...

What is the best way to display the output after retrieving an array?

Database : --> product table P_id P_name P_uploadKey 1 Cemera 7365 2 Notebook 7222 3 Monitor 7355 4 Printer 7242 --> buy table B_id P_id B_nam ...

Injecting components into the DOM using JavaScript in Vue.js

I am currently developing a GUI for a webgame using Vue.JS and opting to use http-vue-loader instead of Webpack or similar tools. Personally, I find them cumbersome and prefer to avoid using them. Typically, in order to integrate my components into the DO ...

Automating Image Downloads with Puppeteer by Adding Authentication Query String to Image URL

Attempting to save images stored in a web-space account can be challenging. Accessing the private space with credentials and retrieving the image link using Puppeteer works smoothly. However, when the src attribute of the image includes additional authenti ...

Tips for implementing multiple middlewares in Next.js using the middleware.ts script

In the development of my Next.js project, I am exploring the implementation of multiple middleware without depending on external packages. Although I have seen examples of using a single middleware in Next.js with the next-connect package, I aim to achieve ...

What steps can I take to avoid my Bootstrap Alert overlapping items in my Nav bar when displayed?

Here is the code from my _notices.html.erb file: <% flash.each do |msg_type, message| %> <div class="row pt-6 alert-messages"> <div class="col-lg-6 offset-lg-3"> <div id="inner-message" class=" ...

unable to see the new component in the display

Within my app component class, I am attempting to integrate a new component. I have added the selector of this new component to the main class template. `import {CountryCapitalComponent} from "./app.country"; @Component({ selector: 'app-roo ...

Sending data from JavaScript to PHP in the same function

Currently, I am encountering an issue related to passing JavaScript variables to PHP within the same function. Here is a snippet of my code: else if(msg_type[i] == 'code' ){ var code_action = 'test'; <?php function foob ...

Why can't we import Angular 4 as a library similar to AngularJS?

Why was AngularJS introduced as a script to import in an HTML page? However, in the newer version Angular 4, we need to use a web server to launch the application? Is it because AngularJS is not considered a framework but Angular 4 is? Thank you. ...

How to utilize JS variables for filtering an array in EJS?

Is there a way to filter my user array based on the "username" variable in JavaScript? On the server side: var users = data.filter(u => u.id.startsWith('user_')).map(u => u.value); // [{"username": "arin2115", "som ...

A guide on changing state in React Native

Currently, I am in the process of developing a lightweight project with React Native, and I have come across some challenges that I am finding difficult to overcome. :( On one of the pages in my project, I have included a pair of buttons - one labeled Yes ...

What are some strategies for implementing dynamic script generation within an AJAX response?

I am exploring a new AJAX design approach where a script is returned to handle and show data. The JSON response below is currently functional, but I would appreciate advice on how to better organize the application for future maintenance. { payload: " ...