-1

I am writing a simple webserver with micropython. I want to switch on a relay for a certain duration (given in input by the user from the HTML form). When the relay is off, I display a div with the input form for the duration and the activation button. When the relay is on, the same div is replaced with a countdown; when the relay is on I want to refresh the div every second so that the countdown is updated. When the relay is off, I don't want the div to update because otherwise, if you try to input the duration, every second the input number in the box is cleared.

My div is updated by the following script:

  <script>
    $(document).ready(function () {
      setInterval(function () {
       
        $("#div_name").load(window.location.href + " #heatingDiv");
        
      }, 1000);
    });
  </script>

The div is:

  <div id="div_name">
    <h1>Title</h1>
    insert_content
  </div>

The keyword "insert_content" is replaced with the HTML code inside the micropython program (accordingly to the relay state) before the HTML response is sent.

With the previous code everything works fine except for the fact that the div is updated every second even when the relay is off, making it impossible to input the duration in the form.

What I'd like to do is passing an argument to the script similarly as when one uses onClick to call it (I can modify "state" within micropython before sending the response):

  <div id="div_name(state)">
    <h1>Title</h1>
    insert_content
  </div>

and the script should look like:

  <script>
    $(document).ready(function () {
      setInterval(function (var state) {
        
        if(state){
        $("#div_name").load(window.location.href + " #heatingDiv");
        }
        
      }, 1000);
    });
  </script>

Of course this does not work because id=div_name is not a function call: it is just to give an idea of what I'd like to achieve. How can I do that?

LucioPhys
  • 161
  • 9

1 Answers1

1

Why not use a data attribute:

const $div = $("#div_name");
const state = $div.data('state');

if (state) {
  setInterval(function() {
    $div.load(window.location.href + " #heatingDiv");
  }, 1000);
}

// if you are wanting to do the interval to check if the state changes, you could change it around
setInterval(function() {
  const state = $div.data('state');

  if (state) {
    $div.load(window.location.href + " #heatingDiv");
  }
}, 1000);
<div id="div_name" data-state="state">
  <h1>Title</h1>
  insert_content
</div>

Perhaps if you are only wanting to run the load when the state changes, you may be better of with a MutationObserver watching the data attribute instead of a timeout

Pete
  • 57,112
  • 28
  • 117
  • 166
  • Hi, thank you so much! I only have one last problem: the script won't read the value of the div state unless the page is reloaded. Indeed, when I click the activation button (which reloads the page for other reasons) the div begins to update. But when the relay switches off (and the div state turns to false) the script continues to reload the div because there was no reload of the whole html page. This is strange because I've implemented the second version of your function, where `const state=div.data('state')` is inside the interval function so it should run iteratively. How can I fix that? – LucioPhys Aug 19 '22 at 18:17
  • Ok so the problems were two: first of all, `.data()` does not update the reading value but `.attr()` does (https://stackoverflow.com/questions/8707226/jquery-data-does-not-work-but-attr-does). The second problemi is that when the div is updated by the script its new attribute value is not read if the page is not reloaded, not even by `.attr()`. I solved this with nesting divs: the outer one is the one updated by the script, and the inner one is the one containing the `data-state` attribute that needs to be read by the script. Thank you for the answer :) – LucioPhys Aug 19 '22 at 21:33