0

***UPDATE I've done away with table elements as suggested and am using CSS. I've also seen that there's a "form" attribute, I've tried that, too. When I submit, it is still acting as it did before - sending the wrong value because it was sending the whole table. I've updated the below with the updated HTML output and the PHP code. It looks correct, this is my latest attempt. What am I missing?


I am using PHP to create a form for each row of data. I call to PHP via AJAX. The form builds correctly. Each row correctly lists its values and is in its own form. In this example, there are three rows, thus three forms. When I submit a username on the first row, the ID being sent is from the third row. Not sure what is going on.

AJAX call to PHP FORM - Home Page

<script>
    window.onload = function signupForm() {       
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() {
                if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    document.getElementById("signupForm").innerHTML = this.responseText;
                }
        }
        xmlHttp.open("GET", "ajaxInput.php", true); 
        xmlHttp.send(); 
    }
</script>

PHP FORM - signupForm.php

<?php
    $con=mysqli_connect("localhost","xxxxxx","xxxxxxx","xxxxxxxx");
    // Check connection
    if (mysqli_connect_errno())
    {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
    }

    $result = mysqli_query($con,"SELECT id, DATE_FORMAT(startTime, '%b-%d-%Y') as eventDate, endTime FROM events
    WHERE now() < endTime");

    echo "
        <style>
            .table { display: table; } 
            .table>* { display: table-row; }
            .table>*>* { display: table-cell; padding: 5px; border-style: inset;}        
        </style>

        <div class='table'>     
        <div>    
            <div><b>Event Id</b></div>
            <div><b>Date</b></div>
            <div><b>@username</b></div>
            <div><b>Sign Up!</b></div>
        </div>";

    while($row = mysqli_fetch_array($result))
    {
    //echo "<form action='ajaxSignup.php' method='post'>";
    echo "<div>";
    echo "<div>" . $row['id'] . "</div>";
    echo "<div>" . $row['eventDate'] . "</div>";
    echo "<div><form id='form" .$row['id']. "' method='post'><input class='formSignup' type='text' name='pi_username' id='pi_username' maxlength='20' placeholder='@username' form='form" .$row['id']. "'></div>";
    echo  "<div><input class='formSignup' type='hidden' name='event_id' id='event_id' value='" . $row['id'] . "' form='form" .$row['id']. "'>
    <input name='submit". $row['id'] . "' type='submit' value='Sign up!' onclick='signup(); return false;'></form></div>";
    echo "</div>";
    }
    //echo "</div>";
    echo "</div>";

    mysqli_close($con);

?>

The table draws correctly. I've put form tag in various places as well. Below, I'm using the form attribute in the input tags. The table is being drawn with CSS instead of the table elements.

<html>
   <head></head>
   <body>
      <p>Something here</p>
      <div id="signupForm">
         <style>
            .table { display: table; } 
            .table>* { display: table-row; }
            .table>*>* { display: table-cell; padding: 5px; border-style: inset;}        
         </style>
         <div class="table">
            <div>
               <div><b>Event Id</b></div>
               <div><b>Date</b></div>
               <div><b>@username</b></div>
               <div><b>Sign Up!</b></div>
            </div>
            <div>
               <div>11</div>
               <div>Feb-25-2021</div>
               <div><input class="formSignup" type="text" name="pi_username" id="pi_username" maxlength="20" placeholder="@username" form="form11"></div>
               <div>
                  <input class="formSignup" type="hidden" name="event_id" id="event_id" value="11" form="form11">
                  <form id="form11" method="post"><input name="submit11" type="submit" value="Sign up!" onclick="signup(); return false;"></form>
               </div>
            </div>
            <div>
               <div>12</div>
               <div>Feb-26-2021</div>
               <div><input class="formSignup" type="text" name="pi_username" id="pi_username" maxlength="20" placeholder="@username" form="form12"></div>
               <div>
                  <input class="formSignup" type="hidden" name="event_id" id="event_id" value="12" form="form12">
                  <form id="form12" method="post"><input name="submit12" type="submit" value="Sign up!" onclick="signup(); return false;"></form>
               </div>
            </div>
            <div>
               <div>13</div>
               <div>Feb-27-2021</div>
               <div><input class="formSignup" type="text" name="pi_username" id="pi_username" maxlength="20" placeholder="@username" form="form13"></div>
               <div>
                  <input class="formSignup" type="hidden" name="event_id" id="event_id" value="13" form="form13">
                  <form id="form13" method="post"><input name="submit13" type="submit" value="Sign up!" onclick="signup(); return false;"></form>
               </div>
            </div>
         </div>
      </div>

As can be seen in the PHP, each row is its own form. But looking at the Elements in developer tools, the form is closing early. I think this is related to the issue. Elements

When I enter a username on row one (top row), the username doesn't seem to make it and the ID that does make it is 13 instead of 11.

AJAX Script to process Submit button onclick (Home page)...

<script>
    function signup() {
        var elements = document.getElementsByClassName("formSignup");
        var formData = new FormData(); 
        for(var i=0; i<elements.length; i++) {
            formData.append(elements[i].name, elements[i].value);
        }
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() {
            if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                document.getElementById("signupSuccess").innerHTML = this.responseText;
            }
        }
        xmlHttp.open("post", "ajaxSignup.php"); 
        xmlHttp.send(formData); 
        }
</script>

PHP code on signup page. I have some echos early on that show the id is 13, not 11 and no username is present.

<?php
    $pi_username = $high_score = $attempts = $event_id = "";
    echo $event_id;
    echo $pi_username;

    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $pi_username = test_input($_POST["pi_username"]);
        $event_id = test_input($_POST["event_id"]);
    }

    function test_input($data) {
        $data = trim($data);
        $data = stripslashes($data);
        $data = htmlspecialchars($data);
        return $data;
    }

    echo $event_id;
    echo $pi_username;

    if($_SERVER["REQUEST_METHOD"] == "POST") {
        /* Attempt MySQL server connection. Assuming you are running MySQL
        server with default setting (user 'root' with no password) */
        $link = mysqli_connect("localhost", "xxxxxxx", "xxxxxxx", "xxxxxx");
        
        // Check connection
        if($link === false){
            die("ERROR: Could not connect. " . mysqli_connect_error());
        }
        
        //check if user has already signed up for event
        $alreadySignedUp = mysqli_query($link, "SELECT count(*) AS total FROM signup WHERE event_id = $event_id AND pi_username = '$pi_username'");
        while ($worm = mysqli_fetch_array($alreadySignedUp)){
            //echo $bird['total'];
            if($worm['total'] >= 1 ){
                echo "You have already signed up for this event.";
                echo $event_id;
                echo $pi_username;
                echo $worm['total'];
                mysqli_close($link);
                return; 
            }
        }
    
        // Attempt insert query execution
        $sql = "INSERT INTO signup (event_id, pi_username) VALUES ('$event_id', '$pi_username')";
        if(mysqli_query($link, $sql)){
            echo "You have been successfully added to event ".$event_id."!";
            mysqli_close($link);
            return;
        } else{
            echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
        }
    }
    else {
        echo "Don't forget to submit your high scores before you leave!";
   }   
?>

Where am I going wrong?

  • I'm going blind from all those `\"`. Use single quotes around the attributes so you don't need to escape them. – Barmar Feb 25 '21 at 05:30
  • Your HTML is invalid. You can't have `
    ` in one `` and then the matching `` in a different ``. See https://stackoverflow.com/a/24849864/1491895 for how to have each table row be a different form.
    – Barmar Feb 25 '21 at 05:34
  • Barmar - yeah, just caught that I was missing a . But that didn't fix it. I will review the link to have each table row be a different form. Thank you. Yes, I will go for single quotes. Sorry for your blindness. :) – Justin Schroeder Feb 25 '21 at 05:49
  • DigitalDrifter - Thank you, I will look into making a unique form for each row. – Justin Schroeder Feb 25 '21 at 05:50
  • I've tried the CSS method of creating a table, also tried the 'form' attribute for the input tag, still not working. What am I doing wrong? – Justin Schroeder Feb 26 '21 at 02:44

1 Answers1

0

The signup() function was looking for elements with the same class (formSignup). All input fields had the same class name and were all being sent to the signup() function. I've updated the class name to be unique for each row. Now only a single row is being sent. The signup() function was updated to:

window.onload = function signupForm(getClass) {       
        var xmlHttp = new XMLHttpRequest(getClass);

Example of an input field with a unique class name:

<input class='formSignup" .$row['id']. "' type='hidden' name='event_id' id='event_id' value='" . $row['id'] . "' form='form" .$row['id']. "'>

Removed table elements and created a CSS-styled 'table' as suggested. All working now. Question updated with CSS-Styled table.