I'm trying to make a web application (with PHP) that lists TV Series episodes and you can click on a button (the circles with a pipe in it) next to episode title to check or uncheck your progress. I want to use AJAX for this, but the buttons work only for the second click. After the second click, the page doesn't refresh so AJAX seems to work.
How can I solve this problem?

The relevant code snippets:
series1.php:
<?php
$json_string = file_get_contents("series.json");
$series = json_decode($json_string, true);
$series1 = $series[0];
$json_string = file_get_contents("users.json");
$users = json_decode($json_string, true);
$active_user = [];
$has_user = false;
foreach ($users as $user) {
if ($user["login"]) {
$active_user = $user;
$has_user = true;
}
}
if (isset($_GET["logout"])) {
foreach ($users as $key => $user) {
if ($user["login"]) {
$users[$key]["login"] = false;
$has_user = false;
$active_user = [];
}
}
}
if (isset($_GET["watched"])) {
foreach ($users as $key => $user) {
if ($user["login"]) {
$users[$key]["watched"]["series1"] = $_GET["watched"] - 1;
}
}
}
if (isset($_GET["unwatched"])) {
foreach ($users as $key => $user) {
if ($user["login"]) {
$users[$key]["watched"]["series1"] = $_GET["unwatched"];
}
}
}
$new_array = json_encode($users, JSON_PRETTY_PRINT);
file_put_contents("users.json", $new_array);
?>
...
<section id="scroll" class="bg-dark text-white py-5">
<?php $i = 1; ?>
<?php foreach($series1["episodes"] as $episode): ?>
<div class="container px-0">
<div class="row gx-5 align-items-center">
<?php if($has_user): ?>
<?php if($i <= $active_user["watched"]["series1"]): ?>
<?php if($i % 2 == 1): ?>
<div class="col-lg-5 order-lg-2">
<div class="p-1 py-5"><img class="img-fluid rounded" src="<?= $episode[$i]["cover"]?>" alt="..."/></div>
</div>
<div class="col-lg-7 order-lg-1">
<div class="p-1 py-5">
<h2 class="display-6">
<p class="idnum"><?= $i ?></p>
<?= $episode[$i]["title"]?>
<button class="uncheck">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</svg>
</button>
</h2>
<p class="text-white-50">Episode aired <?= $episode[$i]["date"]?> | IMDb rating: <?= $episode[$i]["rating"]?></p>
<p><?= $episode[$i]["plot"]?></p>
</div>
</div>
<?php else: ?>
<div class="col-lg-5">
<div class="p-1 py-5"><img class="img-fluid rounded" src="<?= $episode[$i]["cover"]?>" alt="..."/></div>
</div>
<div class="col-lg-7">
<div class="p-1 py-5">
<h2 class="display-6">
<p class="idnum"><?= $i ?></p>
<?= $episode[$i]["title"]?>
<button class="uncheck">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</svg>
</button>
</h2>
<p class="text-white-50">Episode aired <?= $episode[$i]["date"]?> | IMDb rating: <?= $episode[$i]["rating"]?></p>
<p><?= $episode[$i]["plot"]?></p>
</div>
</div>
<?php endif; ?>
<?php else: ?>
<?php if($i % 2 == 1): ?>
<div class="col-lg-5 order-lg-2">
<div class="p-1 py-5"><img class="img-fluid rounded" style="filter: grayscale(1);" src="<?= $episode[$i]["cover"]?>" alt="..."/></div>
</div>
<div class="col-lg-7 order-lg-1">
<div class="p-1 py-5">
<h2 class="display-6 text-white-50">
<p class="idnum"><?= $i ?></p>
<?= $episode[$i]["title"]?>
<button class="check">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z"/>
</svg>
</button>
</h2>
<p class="text-white-50">Episode aired <?= $episode[$i]["date"]?> | IMDb rating: <?= $episode[$i]["rating"]?></p>
<p class="text-white-50"><?= $episode[$i]["plot"]?></p>
</div>
</div>
<?php else: ?>
<div class="col-lg-5">
<div class="p-1 py-5"><img class="img-fluid rounded" style="filter: grayscale(1);" src="<?= $episode[$i]["cover"]?>" alt="..."/></div>
</div>
<div class="col-lg-7">
<div class="p-1 py-5">
<h2 class="display-6 text-white-50">
<p class="idnum"><?= $i ?></p>
<?= $episode[$i]["title"]?>
<button class="check">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z"/>
</svg>
</button>
</h2>
<p class="text-white-50">Episode aired <?= $episode[$i]["date"]?> | IMDb rating: <?= $episode[$i]["rating"]?></p>
<p class="text-white-50"><?= $episode[$i]["plot"]?></p>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<?php $i = $i + 1; ?>
<?php endforeach; ?>
</section>
scripts.js:
let section = document.querySelector("section");
function handleCheckButtonClick(event) {
if (!event.target.matches("button")) return;
let xhr = new XMLHttpRequest();
if (event.target.classList.contains("check")) {
console.log("check");
xhr.open("GET", `seriesgenerator.php?unwatched=${document.querySelector(".idnum").innerHTML}`, true);
xhr.addEventListener("readystatechange", function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
section.innerHTML = xhr.responseText;
} else {
console.log("Error");
}
}
}, false);
xhr.send(null);
} else if (event.target.classList.contains("uncheck")) {
console.log("uncheck");
xhr.open("GET", `seriesgenerator.php?watched=${document.querySelector(".idnum").innerHTML}`, true);
xhr.addEventListener("readystatechange", function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
section.innerHTML = xhr.responseText;
} else {
console.log("Error");
}
}
}, false);
xhr.send(null);
}
}
section.addEventListener("click", handleCheckButtonClick);
And the seriesgenerator.php is echoing the exact same code in the series1.php section part, but here's the code:
<?php
$json_string = file_get_contents("series.json");
$series = json_decode($json_string, true);
$series1 = $series[0];
$json_string = file_get_contents("users.json");
$users = json_decode($json_string, true);
$active_user = [];
$has_user = false;
foreach ($users as $user) {
if ($user["login"]) {
$active_user = $user;
$has_user = true;
}
}
if (isset($_GET["logout"])) {
foreach ($users as $key => $user) {
if ($user["login"]) {
$users[$key]["login"] = false;
$has_user = false;
$active_user = [];
}
}
}
if (isset($_GET["watched"])) {
foreach ($users as $key => $user) {
if ($user["login"]) {
$users[$key]["watched"]["series1"] = $_GET["watched"] - 1;
}
}
}
if (isset($_GET["unwatched"])) {
foreach ($users as $key => $user) {
if ($user["login"]) {
$users[$key]["watched"]["series1"] = $_GET["unwatched"];
}
}
}
$new_array = json_encode($users, JSON_PRETTY_PRINT);
file_put_contents("users.json", $new_array);
$html = "";
$i = 1;
foreach ($series1["episodes"] as $episode) {
$html = $html."<div class='container px-0'><div class='row gx-5 align-items-center'>";
if ($has_user) {
if ($i <= $active_user["watched"]["series1"]) {
if($i % 2 == 1) {
$html = $html."<div class='col-lg-5 order-lg-2'><div class='p-1 py-5'><img class='img-fluid rounded' src='".$episode[$i]["cover"]."' alt='...'/></div></div><div class='col-lg-7 order-lg-1'><div class='p-1 py-5'><h2 class='display-6'><p class='idnum'>".$i."</p>".$episode[$i]["title"]."<button class='uncheck'><svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-check-circle-fill' viewBox='0 0 16 16'><path d='M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z'/></svg></button></h2><p class='text-white-50'>Episode aired ".$episode[$i]["date"]." | IMDb rating: ".$episode[$i]["rating"]."</p><p>".$episode[$i]["plot"]."</p></div></div>";
} else {
$html = $html."<div class='col-lg-5'><div class='p-1 py-5'><img class='img-fluid rounded' src='".$episode[$i]["cover"]."' alt='...'/></div></div><div class='col-lg-7'><div class='p-1 py-5'><h2 class='display-6'><p class='idnum'>".$i."</p>".$episode[$i]["title"]."<button class='uncheck'><svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-check-circle-fill' viewBox='0 0 16 16'><path d='M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z'/></svg></button></h2><p class='text-white-50'>Episode aired ".$episode[$i]["date"]." | IMDb rating: ".$episode[$i]["rating"]."</p><p>".$episode[$i]["plot"]."</p></div></div>";
}
} else {
if($i % 2 == 1) {
$html = $html."<div class='col-lg-5 order-lg-2'><div class='p-1 py-5'><img class='img-fluid rounded' style='filter: grayscale(1);' src='".$episode[$i]["cover"]."' alt='...'/></div></div><div class='col-lg-7 order-lg-1'><div class='p-1 py-5'><h2 class='display-6 text-white-50'><p class='idnum'>".$i."</p>".$episode[$i]["title"]."<button class='check'><svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-check-circle' viewBox='0 0 16 16'><path d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/><path d='M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z'/></svg></button></h2><p class='text-white-50'>Episode aired ".$episode[$i]["date"]." | IMDb rating: ".$episode[$i]["rating"]."</p><p class='text-white-50'>".$episode[$i]["plot"]."</p></div></div>";
} else {
$html = $html."<div class='col-lg-5'><div class='p-1 py-5'><img class='img-fluid rounded' style='filter: grayscale(1);' src='".$episode[$i]["cover"]."' alt='...'/></div></div><div class='col-lg-7'><div class='p-1 py-5'><h2 class='display-6 text-white-50'><p class='idnum'>".$i."</p>".$episode[$i]["title"]."<button class='check'><svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-check-circle' viewBox='0 0 16 16'><path d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/><path d='M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z'/></svg></button></h2><p class='text-white-50'>Episode aired ".$episode[$i]["date"]." | IMDb rating: ".$episode[$i]["rating"]."</p><p class='text-white-50'>".$episode[$i]["plot"]."</p></div></div>";
}
}
} else {
if($i % 2 == 1) {
$html = $html."<div class='col-lg-5 order-lg-2'><div class='p-1 py-5'><img class='img-fluid rounded' src='".$episode[$i]["cover"]."' alt='...'/></div></div><div class='col-lg-7 order-lg-1'><div class='p-1 py-5'><h2 class='display-6'>".$episode[$i]["title"]."</h2><p class='text-white-50'>Episode aired ".$episode[$i]["date"]." | IMDb rating: ".$episode[$i]["rating"]."</p><p>".$episode[$i]["plot"]."</p></div></div>";
} else {
$html = $html."<div class='col-lg-5'><div class='p-1 py-5'><img class='img-fluid rounded' src='".$episode[$i]["cover"]."' alt='...'/></div></div><div class='col-lg-7'><div class='p-1 py-5'><h2 class='display-6'>".$episode[$i]["title"]."</h2><p class='text-white-50'>Episode aired ".$episode[$i]["date"]." | IMDb rating: ".$episode[$i]["rating"]."</p><p>".$episode[$i]["plot"]."</p></div></div>";
}
}
$html = $html."</div></div>";
$i = $i + 1;
}
echo $html;
?>