lStoilov
lStoilov

Reputation: 1339

Change multiple attr of a div with JS

I have a bootstrap progress bar that is getting its data by a js function

Here is the progress bar

 <div class="progress-bar progress-bar-success" role="progressbar"
  aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width:40%" id="progress">40%</div>

And here is the js to update the bar

function refreshProgress(){
        $('#progress').load('progress.php', function(){
           setTimeout(refreshTableData, 5000);
        });

The problem I have

The js updates only the content of the div but can't figure out how to update also the values of aria-valuenow="40" and style="width:40%"

I was thinking of something like

$("#progress").attr({
      "aria-valuenow" : "the progress.php value",
      "style" : "the progress.php value"
    });

But not sure how to do it, if that is the way that it can be done.

UPDATE

What I am aiming for is aria-valuemax="100" style="width:40%" as well as the div content to update in the same time with one call to progress.php

Upvotes: 1

Views: 397

Answers (3)

Richard
Richard

Reputation: 1038

First of all, the way you try to update your attr is the good one.

$("#progress").attr({
  "aria-valuenow" : "the progress.php value",
  "style" : "the progress.php value"
});

What you want now is to put the number returned by your php in your content as well as your attribute aria-valuenow

A way to do it is by making an xhr call with the anwser returned by the server

setInterval(
$.post(
  "progress.php",
  function(resp) {
       // first I check if my answer is 100 so I stop the interval
       if(resp === '100') {return false}
       //if not, I update my bar
       $("#progress").attr("aria-valuenow",resp).css('width',resp+'%').empty().text(resp+"%");
  }
),
5000);

Upvotes: 1

Nick
Nick

Reputation: 147216

.attr will take an object as you are currently using. This is a little demo showing that:

let value = 0;
const updateProgress = (value) => {
  const pb = $('#progress');
  value = value + 10;
  pb.attr({
    "aria-valuenow": value,
    "style": 'width:' + value + '%'
  }).text(value + '%');
  if (value <= 90) {
    setTimeout(updateProgress, 1000, value);
  }
}

updateProgress(value);
<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>
<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">
<div class="progress" style="height:10px; width:90%; margin: 10px auto; height: 20px">
  <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width:40%" id="progress">40%</div>
</div>

Upvotes: 1

connexo
connexo

Reputation: 56783

$.attr will accept an object as you are suggesting: https://api.jquery.com/attr/#attr-attributes

Setting several attributes at once

To change the alt attribute and add the title attribute at the same time, pass both sets of names and values into the method at once using a plain JavaScript object. Each key-value pair in the object adds or modifies an attribute:

$("#greatphoto").attr({
  alt: "Beijing Brush Seller",
  title: "photo by Kelly Clark"
});

What you could also do if jQuery wouldn't support that:

const update = {
  "aria-valuenow" : "the progress.php value",
  "style" : "the progress.php value"
}
for (const prop in update) {
  $("#progress").attr(prop, update[prop]);
}

Alternatively, if you don't want to define an additional constant, you can also go with an inline object literal:

for (const [prop, value] of Object.entries({
    "aria-valuenow" : "the progress.php value",
    "style" : "the progress.php value"
  })
) {
  $("#progress").attr(prop, value);
}

Something along these lines will be what jQuery does internally anyway.

Upvotes: 0

Related Questions