skip to Main Content

I am fairly new to AJAX and struggling with this thing which i believe is rather a problem with toggle.php. I have this code which works for the most part. But when page is reloaded manually and toggle is = ON, the states get mixed so button is OFF. PHP does not seem to reset and is ON. I tried changing a few things but cant seem to to find the logic error.

The fetchToggleStatus function was added by chatgpt and brought some help..so might as well delete it.

toggle button.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Button Toggle with AJAX and PHP</title>
</head>
<body>

<button id="toggleButton">Toggle</button>
<div id="resultContainer"></div>

<script>
    document.addEventListener('DOMContentLoaded', function () {
        var toggleButton = document.getElementById('toggleButton');
        var resultContainer = document.getElementById('resultContainer');

        // Fetch the initial toggle state when the page loads
        fetchToggleStatus();

        toggleButton.addEventListener('click', function () {
            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'toggle.php', true);

            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    resultContainer.innerHTML = xhr.responseText;
                    updateButtonAppearance();
                }
            };

            xhr.send();
        });

        function fetchToggleStatus() {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', 'toggle.php', true);

            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    resultContainer.innerHTML = xhr.responseText;
                    updateButtonAppearance();
                }
            };

            xhr.send();
        }

        function updateButtonAppearance() {
            var currentText = toggleButton.innerText;
            var newColor = currentText === 'Toggle OFF' ? 'green' : 'red';
            toggleButton.style.backgroundColor = newColor;
            toggleButton.innerText = currentText === 'Toggle OFF' ? 'Toggle ON' : 'Toggle OFF';
        }
    });
</script>

</body>
</html>

toggle.php

<?php
session_start();

// Check if the toggle is set in the session, initialize if not set
if (!isset($_SESSION['toggle_status'])) {
    $_SESSION['toggle_status'] = false;
}

// Toggle the status only when a POST request is received
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $_SESSION['toggle_status'] = !$_SESSION['toggle_status'];
}

// Return the current status
if ($_SESSION['toggle_status']) {
    echo "Toggle is ON";
} else {
    echo "Toggle is OFF";
}
?>

2

Answers


  1. When you reload the page, the session cookie is still sent to the server so when isset($_SESSION['toggle_status']) is called it returns True.

    Here is your problem, when you reload the page the value in the session can be set to true. So when doing a get Request you should set the session value to False.

    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        $_SESSION['toggle_status'] = false;
    }
    
    Login or Signup to reply.
  2. PHP does not seem to reset

    Correct, and it should not, you’re tracking toggle state in the session, which survives across requests, that’s the whole point of the session.

    The problem is you’re using that saved state to display the text in your resultContainer, but you don’t use it to set the state of the button. The button simply toggles every time you click it, no matter what state it starts in. So they will get out of sync.

    The fix is to use the saved state from the session to set your button state, just like you do for the container text. You can do that by passing the state received from toggle.php to updateButtonAppearance(), and using it instead of the current button text.

    • Update all uses of updateButtonAppearance() to pass the received text as a parameter:

      updateButtonAppearance(xhr.responseText);
      
    • And update updateButtonAppearance() to use that state:

      function updateButtonAppearance(state) {
          var newColor = state === 'Toggle is OFF' ? 'green' : 'red';
          toggleButton.style.backgroundColor = newColor;
          toggleButton.innerText = state === 'Toggle is OFF' ? 'Toggle ON' : 'Toggle OFF';
      }
      
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search