skip to Main Content

I am working on a simple web page that stores the start time, then displays the time when you click a button sort of like a timer. I came across this problem where when clicking a button in a form, it reloads the script overwriting the start time variable. Here is the code:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>Work Tracker</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
            body {background-color: grey;}
            .button {
            border: none;
            color: rgb(0, 0, 0);
            padding: 15px 32px;
            text-align: right;
            text-decoration: none;
            display: inline-block;
            font-size: 25px;
            margin: 4px 2px;
            cursor: pointer;
            border-radius: 10px;
            }
            .button2 {background-color: #ff0000;}
            #text1 {
                color: black;
                text-align: center;
                font: bold 24px sans-serif;
                background: white;
                padding: 10px;
                border: solid black 2px;
                border-radius: 10px;
            }
        </style>
    </head>
    <body>
        <?php
        date_default_timezone_set('America/Los_Angeles');
        $startTime = date("h:i a");
        echo "<h2>" . $startTime . "</h2>";
        if (isset($_POST["btn-endtimer"])) {
            $endtime = date("h:i a");
            echo "<h2>" . $endtime . "</h2>";
        }
        ?>
        <script type="text/javascript">
            if(starttime === undefined){
                var starttime = "<?php echo "$startTime"; ?>";
                console.log(starttime);
            }
            console.log(starttime);
        </script>
        <form method="post">
            <input type="submit" value="End Timer" name="btn-endtimer" style="background-color:#ffb3b3; height:100px; width:250px; font-size:50px; border-radius: 15px; border-color: #fc9f9f">
        </form>
    </body>
</html>

Here is the webpage: webpage picture
it displays the time when the page was opened as well as a button. When this button is clicked, it runs a line of code that stores the current date, but it reloads the script, so the start time variable is overwritten to the current time. Is there a way to send the starttime variable somewhere so that it can not be changed? This is what is looks like after clicking the button a few minutes later: picture
Update: I have tried session variables, but it seems that the code jumps straight there. For example:

session_start();
echo $_SESSION['a'];
$_SESSION['a'] = "hello world"
echo $_SESSION['a'];

prints

hello world
hello world

Why?

2

Answers


  1. The method post will always refresh the page since PHP code is sent to server and it needs to be loaded typically on new page.

    You can avoid that by using JavaScript function

    <body>
        <?php
        date_default_timezone_set('America/Los_Angeles');
        $startTime = date("h:i a");
        echo "<h2>" . $startTime . "</h2>";
        ?>
        <script>
        window.addEventListener("load", function() {
            var endTime = "";
            var startTime = "<?php echo $startTime; ?>";
            console.log(startTime);
            document.getElementById("end-timer-button").addEventListener("click", function() {
                endTime = new Date().toLocaleTimeString();
                document.getElementById("end-time").innerHTML = endTime;
            });
        });
        </script>
    
        <button id="end-timer-button"
            style="background-color:#ffb3b3; height:100px; width:250px; font-size:50px; border-radius: 15px; border-color: #fc9f9f">End
            Timer</button>
        <h2 id="end-time"></h2>
    </body>
    

    The PHP code is used to create new variable $startTime and store it. The JavaScript code is used to handle the button click and store var = EndTime wich is an empty string that gets value from PHP $startTime. Finally document.getElementById("end-time").innerHTML = endTime; prints out the EndTime variable into <h2 id="end-time"></h2> if you want the time to be displayed above the button. you can simply put it between the PHP code And start of JavaScript like this

    echo "<h2>" . $startTime . "</h2>";
        ?>
        <h2 id="end-time"></h2>
    <script>
    

    Hope this helps / solves your problem

    Login or Signup to reply.
  2. Perhaps the easiest way to interact between browser and server to do what you want
    ( log a time ) would be to use AJAX. Requests are sent without needing to reload the page and provide a better user experience.

    The following would send a time to the server (same page in this instance) – how you deal with that server-side is not specified but would, in most cases, involve writing to a database.

    This demo will fire an ajax request but due to the sandbox will throw an error but inspecting network traffic in console should illustrate what happens.

    // utility to format a Date into a minimal timestring - chose UK for locale
    const gettime=()=>Intl.DateTimeFormat('en-GB', { timeStyle:'medium' } ).format( new Date() );
    
    // utility to display, in the H2 element, the time at any particular moment
    const displaytime=()=>{
        let date=gettime();
        let content=`<div>${date}</div>`;
        document.querySelector('h2').insertAdjacentHTML('beforeend',content)
    };
    
    // the AJAX callback. This can be used to do what ever you need to do once you have logged
    // the time on the server. DOM manipulation, inform user, open window etc
    const callback=(r)=>{
      alert(r)
    };
    
    // There is no need to actually send the time from the client ( it can be modified )
    // - instead you could just send a beacon to say "log now" type thing but for example
    // send the time to the same page.
    const sendtime=()=>{
      let url=location.href;  // or /path/to/script.php etc
      let fd=new FormData();
          fd.set('time',gettime() );
          
      fetch( url,{ method:'post',body:fd } )
        .then(r=>r.text())
        .then(callback)
        .catch(alert)
    };
    
    
    // delegated event listener to respond to button clicks
    document.addEventListener('click',e=>{
      if( e.target instanceof HTMLInputElement && e.target.type=='button' && e.target.name=='btn-endtimer' ){
        displaytime();
        sendtime();
      }
    });
    
    // how initial load time - this could be fetched from db rather than using current time!
    displaytime();
    body {
      background-color: grey;
    }
    /*
      other styles removed as they were not applicable
      to the original code 
    */
    input[name="btn-endtimer"] {
      background-color: #ffb3b3;
      height: 100px;
      width: 250px;
      font-size: 50px;
      border-radius: 15px;
      border-color: #fc9f9f
    }
    <h2></h2>
    
    <input type="button" value="End Timer" name="btn-endtimer" />
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search