0

I am trying to update the class of a button from within a class. At the moment the class only updates after the timer() function is finished but I want it to update when the button is pressed. I can see that the classname is changing but it does not update in time.

function reply_click(clicked_id){
    id = clicked_id;
    var colorSwitch = document.getElementById(id).className;
    if(colorSwitch){
        colorSwitch = color_check(colorSwitch, id);
        console.log(colorSwitch);
        console.log(time());
    }
}

function time(){
    const utcStr = new Date();
    return utcStr;
}

//Checks color of pressed button
function color_check(color, id){
    if(color == "btnRed"){
        alert("Slot already booked!!!!");
    }else if(color == "btnYellow"){
        alert("You have already booked this slot!!!!!");
    }else if(color == "btnGreen"){
        alert("Slot booked!!!!!");
        color = "btnYellow";
        document.getElementById(id).className = color;
        var result = timer(new Date());
        console.log("1: " + result);
    }
    return color;
}

//Access python timer class
function timer(time){
    let Time =  new Date(Date.parse(time));
    const timeMin = Time.getMinutes();
    console.log(Time);
    while (true){
        let currentTime = new Date();
        currentTime = currentTime.getMinutes();
        if((currentTime - timeMin) >= 0.1){
            //ajax post
            fetch('/background_process_test')
      .then(function (response) {
          return response.json();
      }).then(function (text) {
          console.log('GET response:');
          console.log(text.greeting); 
          if(text.greeting == true){
            console.log(text.greeting);
            //add 45 minute timer to recheck the room is empty
        }
      });
            return false;
        }
    }
}

I am trying to update the class in colorCheck()

Sfili_81
  • 2,377
  • 8
  • 27
  • 36
padi Foley
  • 17
  • 3
  • 2
    Please provide your debugging details as a [repro] which also include your HTML and CSS. Also flag accordingly as it seems that you're using JS. – tacoshy Apr 05 '23 at 11:59
  • 1
    If you need something to happen after a specified amount of time, you should use `setTimeout`. The `while` loop blocks your whole process. – Kokodoko Apr 05 '23 at 12:00
  • are those elements dynamically created? – tacoshy Apr 05 '23 at 12:02
  • @tacoshy they arent, there just a list of html buttons – padi Foley Apr 05 '23 at 12:05
  • @Kokodoko Should it not update the classname of the button before entering the while loop? – padi Foley Apr 05 '23 at 12:07
  • No, this is not how it works. The rendering engine passes over "control" to the JS engine, and lets that do its job. Only when control is passed back to the rendering engine, the UI will be updated with any changes your JS might have made. You will need to introduce an "interruption" into your JS, if you want the UI to display earlier - using setTimeout or requestAnimationFrame. Another trick that usually works is to make a "request" for something that needs to be calculated by the rendering engine - such a querying an element's `offsetHeight` property. – CBroe Apr 05 '23 at 12:22
  • Very similar issues, with more explanation: https://stackoverflow.com/questions/19058858/jquery-append-in-loop-dom-does-not-update-until-the-end, https://stackoverflow.com/q/8110905/1427878 – CBroe Apr 05 '23 at 12:24

1 Answers1

0

Not sure if I understand your question correctly, but here is an example of a button that changes color after X minutes, OR when you press it. The setTimeout function runs in the background and won't block other code from executing.

let btn = document.querySelector("button")
btn.addEventListener("click", (e) => {
    e.target.classList.add("active")
})

setTimeout(() => {
    btn.classList.add("active")
}, 1000)
button {
  padding: 10px;
  font-size:1em;
  background-color:lightblue;
  border:0;
}
.active {
  background-color:darkblue;
  color:white;
}
<button>
Click here
</button>
Kokodoko
  • 26,167
  • 33
  • 120
  • 197