Attempting to assign a value to the Progress Circle

Can I modify the code to incorporate a hardcoded number instead of displaying "Goals completed:" and still have the progress bar reflect the percentage? I want to hide the prompt for users to input a number and handle all updates behind the scenes.

Essentially, I want to remove the whole "Goals Completed: (input box)" message. Instead, I want to set a fixed value like goals = 69, and have the progress circle dynamically show 60% in the center with 69 out of 115 goals completed, along with the green outer circle matching that. Users should not be able to enter or see an input prompt for entering the number of completed goals. The only way to adjust the completed goals count should be through modifications in the JavaScript code.

This is my current code:

document.querySelector('.goals').addEventListener('change', function() {
  var goals = parseInt(this.value);
  var circle = document.querySelector('circle');
  var percentdiv = document.querySelector('.percent');
  var completed = document.querySelector('.completed');
  completed.innerHTML = goals;
  var totaldiv = document.querySelector('.total');
  var total = totaldiv.innerHTML;
  var pc = goals * 100 / total;
  var r = circle.getAttribute('r').replace('%', '') * percentdiv.clientWidth / 100; //actual radius of the circle
  var c = Math.PI * (r * 2); //circumference is 2*pi*r

  if (isNaN(goals)) {
    pc = 100;
  } else if (pc < 0) {
    pc = 0;
  } else if (pc > 100) {
    pc = 100;
  }
  document.querySelector('.number h2').innerHTML = Math.floor(pc) + '<span>%</span>';

  var length = pc * c / 100;

  circle.style.strokeDasharray = length + ' ' + (c - length);
  circle.style.strokeWidth = (length > 0) ? '5%' : 0;
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#progress-bar {
  position: absolute;
  left: 50%;
  top: 55%;
  transform: translate(-51%, -50%);
  width: 40%;
}

.container {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: space-around;
}

.container .card {
  position: relative;
  width: 400px;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 400px;
  border-radius: 4px;
  text-align: center;
  overflow: hidden;
  transition: 0.5s;
}

.container .card:before {
  content: '';
  position: absolute;
  top: 0;
  left: -50%;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.03);
  pointer-events: none;
  z-index: 1;
}

.percent {
  position: relative;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  border-color: transparent;
  border-width: 0;
  border-style: none;
  rbox-shadow: inset 0 0 50px #000;
  background-image: radial-gradient(#444 0%, #222 70%, transparent 70%, transparent 100%);
  rbackground: #222;
  z-index: 1000;
}

.percent .number {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
}

.percent .number h2 {
  color: #777;
  font-weight: 700;
  font-size: 40px;
  transition: 0.5s;
}

.card:hover .percent .number h2 {
  color: #fff;
  font-size: 60px;
}

.percent .number h2 span {
  font-size: 24px;
  color: #777;
  transition: 0.5s;
}

.card:hover .percent .number h2 span {
  color: #fff;
}

.text {
  position: relative;
  color: #777;
  margin-top: 40px;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 1px;
  text-transform: uppercase;
  transition: 0.5s;
}

svg {
  width: 100%;
  height: 100%;
  z-index: 1000;
}

svg circle {
  fill: none;
  stroke-width: 0;
  stroke-linecap: round;
  stroke: #00ff43;
}
<div class="container">
  <div class="card">
    <div class="box">
      <div class="percent">
        <svg>
                      <circle cx="50%" cy="50%" r="47.5%"></circle>
                    </svg>
        <div class="number">
          <h2>0<span>%</span></h2>
        </div>
      </div>
      <h2 class="text"><span class="completed">0</span> of <span class="total">115</span> Goals Completed</h2>
    </div>
  </div>
</div>
Goals completed: <input class="goals" type='number' />

Answer №1

Instead of embedding the logic to update the circle in the input event handler, create a separate function for it. You can then easily call this function with any number, like setGoals(50), which will update the circle to display 50 of 115 goals completed and 43%.

You have the option to include an input box to change the displayed value or directly call

setGoals(<some number here>)
anywhere in your code.

This is the code snippet you need:

function setGoals(goals) {
  const circle = document.querySelector('circle');
  const percentdiv = document.querySelector('.percent');
  const completed = document.querySelector('.completed');
  completed.innerHTML = goals;
  const totaldiv = document.querySelector('.total');
  const total = totaldiv.innerHTML;
  let pc = goals * 100 / total;
  const r = circle.getAttribute('r').replace('%', '') * percentdiv.clientWidth / 100; //actual radius of the circle
  const c = Math.PI * (r * 2); //circumference is 2*pi*r

  if (isNaN(goals)) {
    pc = 100;
  } else if (pc < 0) {
    pc = 0;
  } else if (pc > 100) {
    pc = 100;
  }
  document.querySelector('.number h2').innerHTML = Math.floor(pc) + '<span>%</span>';

  const length = pc * c / 100;

  circle.style.strokeDasharray = length + ' ' + (c - length);
  circle.style.strokeWidth = (length > 0) ? '5%' : 0;
}

// For testing purposes, set up the input box to edit the number of displayed goals
document.querySelector('.goals').addEventListener('change', (e) => {
  const goals = parseInt(e.target.value);
  setGoals(goals);
});

// On page load, manually set the goals to 50 for demonstration purposes
setGoals(50);
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#progress-bar {
  position: absolute;
  left: 50%;
  top: 55%;
  transform: translate(-51%, -50%);
  width: 40%;
}

.container {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: space-around;
}

.container .card {
  position: relative;
  width: 400px;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 400px;
  border-radius: 4px;
  text-align: center;
  overflow: hidden;
  transition: 0.5s;
}

.container .card:before {
  content: '';
  position: absolute;
  top: 0;
  left: -50%;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.03);
  pointer-events: none;
  z-index: 1;
}

.percent {
  position: relative;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  border-color: transparent;
  border-width: 0;
  border-style: none;
  rbox-shadow: inset 0 0 50px #000;
  background-image: radial-gradient(#444 0%, #222 70%, transparent 70%, transparent 100%);
  rbackground: #222;
  z-index: 1000;
}

.percent .number {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
}

.percent .number h2 {
  color: #777;
  font-weight: 700;
  font-size: 40px;
  transition: 0.5s;
}

.card:hover .percent .number h2 {
  color: #fff;
  font-size: 60px;
}

.percent .number h2 span {
  font-size: 24px;
  color: #777;
  transition: 0.5s;
}

.card:hover .percent .number h2 span {
  color: #fff;
}

.text {
  position: relative;
  color: #777;
  margin-top: 40px;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 1px;
  text-transform: uppercase;
  transition: 0.5s;
}

svg {
  width: 100%;
  height: 100%;
  z-index: 1000;
}

svg circle {
  fill: none;
  stroke-width: 0;
  stroke-linecap: round;
  stroke: #00ff43;
}
<div class="container">
  <div class="card">
    <div class="box">
      <div class="percent">
        <svg>
                      <circle cx="50%" cy="50%" r="47.5%"></circle>
                    </svg>
        <div class="number">
          <h2>0<span>%</span></h2>
        </div>
      </div>
      <h2 class="text"><span class="completed">0</span> of <span class="total">115</span> Goals Completed</h2>
    </div>
  </div>
</div>
Goals completed: <input class="goals" type='number' />

Testing on Stack Overflow might be challenging, but by using setGoals(50) or another number as input, you can update the displayed goals in the circle. I have included setGoals(50) in the code snippet above to demonstrate displaying 50 goals upon page load.

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 adjusting the position of an infowindow in ArcGIS

I have implemented the use of infowindow in arcgis to display certain information. https://i.sstatic.net/Dnpas.jpg Currently, the infowindow is appearing directly over my icon. Is there a way to adjust its position if it covers the icon? ...

When attempting to load a CSS file, Java automatically redirects to the login page

EDIT** After successfully loading CSS, I encountered an issue where the page kept redirecting back to login.jsp instead of displaying the CSS. Any insights on what might be causing this?https://i.sstatic.net/Ij7Oh.png I attempted to incorporate a custom ...

ReactJs - The pagination feature in MaterialTable is malfunctioning, it is not displaying the correct

I am currently utilizing the Material-table plugin. It successfully displays the data, however, I am facing issues with Pagination and Row per Page dropdown functionality. When trying to click on the next button or select a number of rows, nothing happens. ...

Align numbers vertically inside scrollbar center

I have created a program where you can input a number, and it will count from 0 to the specified number. Currently, the numbers are aligned horizontally up to 12 before starting on a new line. However, I would like the numbers to be arranged vertically fr ...

Tips for effectively parsing extensive nested JSON structures?

JSON Data on PasteBin I need assistance in converting this JSON data into an Object. It seems valid according to jsonlint, but I'm encountering issues with parsing it. Any help would be greatly appreciated. "Data":[{...},{...},] // structured like t ...

Preventing the addition of hash tags to the URL by the anything slider

Why does the Anything Slider add hash tags like #&panel1-1 to the end of the URL? I attempted using hashtags:false but it was unsuccessful. Are there alternative methods to prevent it from creating these hashtags? ...

What is causing the data element to remain unchanged within a Vue.js function and what steps can be taken to ensure its value can be updated?

Using the axios API in the created() function, I am able to access webURLs. When a mouseover event triggers a v-for handler in the HTML file, the index is obtained and assigned to the selectedState data element. Although the value of selectedState changes ...

React has reached the maximum update depth limit

In my current project, I am developing a react application that involves a user inputting a search term and receiving an array of JSON data from the backend. On the results page, I have been working on implementing faceted search, which includes several fi ...

Adding array elements to a JavaScript object

I find myself in a rather unique predicament that I'm struggling to navigate. I have come across some data structured as follows. Please bear with me if I use any incorrect terminology, as I am relatively new to this. usersByName: { "tester&q ...

The issue arises when trying to apply Bootstrap CSS styles to dynamically created elements using JavaScript

I utilized JavaScript to create a Bootstrap Modal and followed the correct classes as outlined in the Bootstrap documentation, but unfortunately, the JavaScript-created elements are not being affected. Even after adding the Bootstrap classes and attribute ...

Dispatching identification to controller after submission

I am encountering an issue with a page that contains the following code: <div class="col-sm-2 displaybutton"> <div data-point-to="displaysHeader"> @using (Html.BeginForm("Administration", "Home", FormMethod.Post)) ...

Change the z-index of divs when clicked

When a button is clicked, I want to iterate through a group of absolutely positioned children divs with varying z-indexes. The goal is for the z-index of the currently visible div to decrease on each click, creating a looping effect where only one div is v ...

One-Time Age Verification Popup Requirement

Hi there! I'm facing a challenge with an age verification pop up on my webpage. Currently, the pop up appears on every page a user lands on, but I only want it to show on their first visit. I've tried using cookies to achieve this but haven' ...

Is there a way to modify the value of an object in a Vuex store using actions in Vue.js?

I have data stored in an array within the state and I need to update a specific object. How can I change the value of the object with id 1 to true using Vuex actions? state.js const array=[] mutations.js storeArray(state, data) { state.array = data ...

Encountering a problem when trying to use event.target.value in an Angular TypeScript application

Here is the code from my app.component.html : <h1>Password Generator</h1> <div> <label>Length</label> </div> <input (input)="onChangeLength($event.target.value)"/> <div> <div> <input ...

Enhance web design with dynamic size pseudo elements using only CSS, no

Before the title, I've added a pseudo element with a slanted background. When the title is wrapped, it increases in height. I've been attempting to make the pseudo element adjust to the title's height, but haven't succeeded yet. I&apos ...

Using Jquery to loop through a function for every select box that is added dynamically

Encountering some challenges with jQuery while attempting to utilize the same function and iterate over select boxes that are dynamically generated with jQuery's clone() method. Here is a snippet of the content being cloned: <select name="expense ...

Fetching information from server proves to be sluggish within AngularJS application

In the process of developing a web application, I am faced with the task of sending numerous $http requests to the server. My front-end is built using AngularJS while the back-end utilizes ExpressJS. The $http requests are currently being made as shown in ...

Detecting the scroll events of elements with the overflow:hidden property

Looking to synchronize scrolling between two different panels or divs? In one element, there's an overflow: auto while the other has overflow: hidden (trying to mimic a grid with frozen columns). I've managed to sync the scroll when it occurs w ...

Issues with CSS animation functionality have been detected in the Edge browser

In this particular div, I have two spans enclosed. I've created a loader which features a circle filling up with red color repeatedly. While everything appears to be functioning smoothly in Google Chrome, there's a noticeable glitch when it comes ...