-1

I'm creating a list with a set of checkboxes similar to the Trello tool, the data is extracted from the MySql database.

When the user selects one of the checkboxes to mark the activity as completed, I use an XMLHttpRequest request to make the asynchronous call of the php route and edit the task status to "completed" in the database. (Thus avoiding page refresh).

Also, I have a bootstrap progress bar that counts the number of rows in the table according to status "completed", "pending" and "total", and I use this data to populate the progress bar dynamically.

However, this bar is only updated when I enter the page or refresh it, I would like it to be updated along with the XMLHttpRequest request that is triggered every time the checkbox undergoes any change.

My question is: Is there any way to fill in the bar progress information according to XMLHttpRequest requests?


//CODE RESPONSIBLE FOR MAKING THE ASYNCHRONOUS REQUEST TO EDIT THE STATUS OF THE CHECKBOX IN THE DATABASE

function checkRealizado(url) {

  let checkRealizado = new XMLHttpRequest();

  checkRealizado.open('POST', url)

  checkRealizado.onreadystatechange = () => {

      if(checkRealizado.readyState == 4 && checkRealizado.status == 200) {

      }

  }

  checkRealizado.send()

}

//CHECKBOX RESPONSIBLE FOR ACTIVATING THE XMLHTTPREQUEST FUNCTION

<label class="marcarConcluido" id="marcarConcluido" for="chkPassport">

   <input onclick="checkRealizado('/tarefa?acao=checkRealizado&id='+<?= $checklist->id //DATA EXTRACTED FROM THE DATABASE, ALL OK HERE ?>)"  class="form-check-input" id="chkPassport" style="margin-right: 8px" type="checkbox">

   <?= $checklist->checklist //DATA EXTRACTED FROM THE DATABASE, ALL OK HERE ?>

</label>

//HTML CODE OF MY PROGRESS BAR

<div id="progressBar" class="progress text-muted" style="height: 6px;" role="progressbar" aria-label="Basic example" aria-valuenow="25" aria-valuemin="0" aria-valuemax="<?= $this->view->getLinhasCheck ?>">

  <progress class="text-muted progress-bar w-100" style="background-color: #fff; height: 6px;" value="<?= $this->view->getLinhasCheckRealizada ?>" max="<?= $this->view->getLinhasCheck ?>"></progress>

</div>

/// $this->view->getLinhasCheckRealizada This variable is responsible for filling in the data according to the number of rows in the database table, everything working so far

// $this->view->getLinhasCheck This variable is responsible for filling in the data according to the number of rows in the database table, everything working so 

This is the result I have so far.

Shadow
  • 33,525
  • 10
  • 51
  • 64

1 Answers1

0

Break your problem down into parts.

  • First part? How do we set the width of the progress bar? The Bootstrap docs show that is easy - just set an inline with the percentage, like style="width: 25%".

  • Next part: How do we get that percentage? You mention you are calculating that on the back end already, depending on the rows completed etc. OK, so your PHP code already has this.

  • How do we get that value to the front end? You'll have to return it in the response to your XMLHttpRequest, right? OK so how do we return and use data in an XMLHttpRequest? A quick search shows us many examples here on SO, here's one: we can just use this.responseText.

  • How do we dynamically update the progress bar once we have the new percentage value? Again, searching here turns up many examles, here's one:

    document.getElementsByClassName('progress-bar').item(0)
      .setAttribute('style', 'width:' + Number(percent) + '%');
    

So put it all together.

Your Javascript
function checkRealizado(url) {
    let checkRealizado = new XMLHttpRequest();
    checkRealizado.open('POST', url)
    checkRealizado.onreadystatechange = () => {
        if(checkRealizado.readyState == 4 && checkRealizado.status == 200) {
            // Response to your request is the percentage
            let percentage = this.responseText;

            // Update the progress bar
            document.getElementsByClassName('progress-bar').item(0)
                .setAttribute('style', 'width:' + Number(percentage) + '%');
            document.getElementsByClassName('progress-bar').item(0)
                .setAttribute('aria-valuenow', percentage);

        }
  }    
  checkRealizado.send()    
}
Your PHP
// ... your code which updates rows, and calculates percentage
// You just want to echo the result so the XMLHttpRequest gets the
// result.  So last thing you do, assuming success is:
echo $percentage;
Notes
  • You might want to consider returning JSON from your request, so that you can include more than just the percentage - maybe something like:

    {
        "status": "OK",
        "message": "",
        "percentage": 42
    }
    

    For eg if the request fails you might want to return/display an error message. Currently if that happens the code will just try to use that error msg as a percentage, which won't work. Some searching turns up plenty of answers here about how to use JSON with XMLHttpRequest, eg: Parsing JSON from XmlHttpRequest.responseJSON

  • You might want to look at using fetch() instead of XMLHttpRequest: Fetch API vs XMLHttpRequest

Don't Panic
  • 13,965
  • 5
  • 32
  • 51