Jump to content

How to get form nested in while loop to work?


Go to solution Solved by Ch0cu3r,

Recommended Posts

If I am calling an undistinguishable amount of records from a database through a while loop, and with each record called a submit button is accompanied with it, how can I get each submit button to respond exclusively to its respective iterated record? A visual of what I am trying to achieve:


 


IxB8S.jpg


 


In the logic behind this, each "Contact" button is linked to its adjacent profile. So, if I click on the "Contact" button next to "Lily," Lily's name is passed on to the next page. However, so far I am met with this:


 


qRvgT.jpg


 


Where no matter which "Contact" button I press, the name of the last iteration is passed on. In this case, even I clicked on "Lily"'s contact button, the name of the last/highest iteration, "Jane", is passed on to the next page.


Here is the code I am stuck with:


list.php:



<?php
session_start();
require_once( "./inc/connect.inc.php");
if(!isset($_SESSION["email_login"])) {
header("location: index.php");
}
else {
}
?>

<?php
if ($searchST) {
while ($row = $searchST->fetch_assoc()) {
echo '<form action="list.php" method="POST">';
echo '<div class="z">';
echo '<div class="x">';
echo '<div class="y">';
echo '<div class="text_info">';
echo "<div id='input_titles'>C1</div><textarea readonly name='c1' id='a' rows='3' cols='54' maxlength='162' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c1"]."</textarea><br />";
echo "<div id='input_titles'>C2</div><textarea readonly name='c2' id='a' rows='3' cols='54' maxlength='162' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c2"]."</textarea><br />";
echo "<div id='input_titles'>C3</div><textarea readonly name='c3' id='a' rows='15' cols='54' maxlength='810' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c3"]."</textarea><br />";
echo "<div id='input_titles'>C4</div><textarea readonly name='c4' id='a' rows='2' cols='54' maxlength='108' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c4"]."</textarea>";
echo '</div>';
echo '<div class="visual_info">';
echo '<div class="p_pic_image">';
echo "<img src='".$row["pic"]."' id='p_pic'> ";
echo '</div>';
echo '<div class="country_and_name">';
echo "<textarea readonly name='country' id='country' rows='1' cols='14'>".$row["country"]."</textarea>";
echo "&nbsp".$row["first_name"];
echo '</div>';
echo '</div>';
echo '<form action="network.php" method="POST">';
echo '<input type="submit" name="message" id="message" value="Message">';
echo '</form>';
echo '</div>';
echo '</div>';
echo '</div>';

if (isset($_POST['message'])) {
$carry = "SELECT `first_name` FROM `users`";
$carryST = $con->query($carry);
if($carryST) {
while ($row = $carryST->fetch_assoc()) {
$_SESSION['to_name'] = $row["first_name"];
$_SESSION['to_id'] = $row["id"];

}
}

$carryST->close();
header("location: compose.php");
exit();
}
echo '</form>';

}

}
$searchST->close();
} else {

}

The page the name of a given profile is supposed to pass through(compose.php):

<body>
<div class="wrapper">
<header>
<?php echo $_SESSION["to_name"]; ?>
<?php echo $_SESSION["to_id"]; ?>
<div class = "prep_stmt">Your message to <?php $_SESSION["to_name"]; ?>...</div>
</header>
</div>

</body>

I know that the session variable is constantly being replaced, but I don't know to approach this. I won't know the exact number of users either so I can't make any absolute forms.

Edited by Ch0cu3r

You dont pass the record id via session. What you need to do is output the record id in a hidden input field in your form.

echo '<input type="hidden" name="id" value="'.$row['id'].'" />';

On the receiving page you can then query the database to return the data you require where the submitted record if matches a row in your database

if(isset($_POST['id']) && is_numeric($_POST['id']))
{
    // run query to get first_name where the submitted record id matches
    $result = $con->query('SELECT first_name FROM users WHERE id = ' . intval($id));
    // make sure a row was return
    if($result->num_rows === 1)
    {
        $row = $result->fetch_assoc();
        echo  '<div class = "prep_stmt">Your message to <?php $_row['first_name']; ?>...</div>';
    }
    else
    {
        // record id does not exist. Output error message
    }
}

 

You dont pass the record id via session. What you need to do is output the record id in a hidden input field in your form.

echo '<input type="hidden" name="id" value="'.$row['id'].'" />';

On the receiving page you can then query the database to return the data you require where the submitted record if matches a row in your database

if(isset($_POST['id']) && is_numeric($_POST['id']))
{
    // run query to get first_name where the submitted record id matches
    $result = $con->query('SELECT first_name FROM users WHERE id = ' . intval($id));
    // make sure a row was return
    if($result->num_rows === 1)
    {
        $row = $result->fetch_assoc();
        echo  '<div class = "prep_stmt">Your message to <?php $_row['first_name']; ?>...</div>';
    }
    else
    {
        // record id does not exist. Output error message
    }
}

 

I've tried integrating what you suggested, but nothing seems to be outputting on the receiving page. Here is my attempt at the merge:

 

list.php

<?php
if ($searchST) {
while ($row = $searchST->fetch_assoc()) {
echo '<div class="z">';
echo '<div class="x">';
echo '<div class="y">';
echo '<div class="text_info">';
echo "<div id='input_titles'>C1</div><textarea readonly name='c1' id='a' rows='3' cols='54' maxlength='162' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c1"]."</textarea><br />";
echo "<div id='input_titles'>C2</div><textarea readonly name='c2' id='a' rows='3' cols='54' maxlength='162' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c2"]."</textarea><br />";
echo "<div id='input_titles'>C3</div><textarea readonly name='c3' id='a' rows='15' cols='54' maxlength='810' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c3"]."</textarea><br />";
echo "<div id='input_titles'>C4</div><textarea readonly name='c4' id='a' rows='2' cols='54' maxlength='108' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c4"]."</textarea>";
echo '</div>';
echo '<div class="visual_info">';
echo '<div class="p_pic_image">';
echo "<img src='".$row["pic"]."' id='p_pic'> ";
echo '</div>';
echo '<div class="country_and_name">';
echo "<textarea readonly name='country' id='country' rows='1' cols='14'>".$row["country"]."</textarea>";
echo "&nbsp".$row["first_name"];
echo '</div>';
echo '</div>';
echo '<form action="list.php" method="POST">';
echo '<input type="submit" name="message" id="message" value="Message">';
echo '</form>';
echo '</div>';
echo '</div>';
echo '</div>';

if (isset($_POST['message'])) {
$carry = "SELECT `first_name` FROM `users`";
$carryST = $con->query($carry);
if($carryST) {
while ($row = $carryST->fetch_assoc()) {
$_SESSION['to_name'] = $row["first_name"];
$_SESSION['to_id'] = $row["id"];

}
}

$carryST->close();
header("location: compose.php");
exit();
}
echo '</form>';

}

}
$searchST->close();
} else {

}

And the receiving page:

<header>
      <?php
      if(isset($_POST['id']) && is_numeric($_POST['id']))
{
    // run query to get first_name where the submitted record id matches
    $toCD = "SELECT `first_name` FROM `users` WHERE `id` = intval($id)";
    $toST = $con->query($toCD);
    // make sure a row was return
    if($toST->num_rows === 1)
    {
        $row = $toST->fetch_assoc();
        echo  "<div class = 'prep_stmt'>Your message to".$_row["first_name"]."...</div>";
    }
    else
    {
        // record id does not exist. Output error message
    }
}
      ?>
    </header>

:confused: Nothing is outputting. I also incorporated Barand the Guru's suggestion of removing the first <form> tags while keeping the second <form> tags surrounding the submit button.

Edited by innovatio

Wheres the hidden input field I suggested that will pass the record id? Currently your form only contains the submit button

echo '<form action="list.php" method="POST">';
echo '<input type="submit" name="message" id="message" value="Message">';
echo '</form>';

Also I see you have a bunch of textareas too. If want to retrieve the contents of these textareas when your form is submitted then you then you will need to move opening <form> tag so it comes before them.

 

EDIT: Is your receiving page compose.php? If so then that is where you should be setting your form action to be. The following code is not needed, as you are not using session any more, it will never not work as you intend it to do

if (isset($_POST['message'])) {
$carry = "SELECT `first_name` FROM `users`";
$carryST = $con->query($carry);
if($carryST) {
while ($row = $carryST->fetch_assoc()) {
$_SESSION['to_name'] = $row["first_name"];
$_SESSION['to_id'] = $row["id"];

}
}

$carryST->close();
header("location: compose.php");
exit();
}

The issue is you are having the form submitted to itself (list.php), you then query the database to retrieve only the first_name with no condition applied to the query. This will result in all the first_name's from the database being returned. 

You are then looping through the results and setting two session variables, to_name to the value of the first_name column, and to_id to the the id column - which is not returned by your query. 

Each time the code iterates over the query results you are overwriting the session variables each time. This will result in only the very last row value being written to the session variables. 

After the code has finished looping over the results of the query you are using a header redirect to compose.php. This will now result in any $_POST data being lost, post data is never sent with a header redirect.

 

Submitting the record id and then retrieving the data from the database where the record id matches the id that was submitted is better solution as I have recommended.

Edited by Ch0cu3r

 

I also incorporated Barand the Guru's suggestion of removing the first <form> tags while keeping the second <form> tags surrounding the submit button.

 

 

My suggestion also included putting the hidden field, containing the id, inside the form.

 

Suggest you put the hidden id field after the second ...

Wheres the hidden input field I suggested that will pass the record id? Currently your form only contains the submit button

echo '<form action="list.php" method="POST">';
echo '<input type="submit" name="message" id="message" value="Message">';
echo '</form>';

Also I see you have a bunch of textareas too. If want to retrieve the contents of these textareas when your form is submitted then you then you will need to move opening <form> tag so it comes before them.

 

EDIT: Is your receiving page compose.php? If so then that is where you should be setting your form action to be. The following code is not needed, as you are not using session any more, it will never not work as you intend it to do

if (isset($_POST['message'])) {
$carry = "SELECT `first_name` FROM `users`";
$carryST = $con->query($carry);
if($carryST) {
while ($row = $carryST->fetch_assoc()) {
$_SESSION['to_name'] = $row["first_name"];
$_SESSION['to_id'] = $row["id"];

}
}

$carryST->close();
header("location: compose.php");
exit();
}

The issue is you are having the form submitted to itself (list.php), you then query the database to retrieve only the first_name with no condition applied to the query. This will result in all the first_name's from the database being returned. 

You are then looping through the results and setting two session variables, to_name to the value of the first_name column, and to_id to the the id column - which is not returned by your query. 

Each time the code iterates over the query results you are overwriting the session variables each time. This will result in only the very last row value being written to the session variables. 

After the code has finished looping over the results of the query you are using a header redirect to compose.php. This will now result in any $_POST data being lost, post data is never sent with a header redirect.

 

Submitting the record id and then retrieving the data from the database where the record id matches the id that was submitted is better solution as I have recommended.

 

The <form> tags containing your suggested input hidden field are at the end of the "echo" tirade. So I will remove the "if (isset($_POST))" code concerning the message button because I understand now that the session method will not get me anywhere. I do not want to pass over the textarea information, just the name and id so I can use those as reference variables when calling a query. Yes, you are correct in that "compose.php" is my receiving page, and by the names of my php pages, you may have already observed that I coding towards a contact -> message system. On the receiving page, the error message shows, to my comfort that at least something is working, and am now trying to get the "isset()" and "isnumeric" conditions to work.

 

 

My suggestion also included putting the hidden field, containing the id, inside the form.

 

And I did just that. I removed the outer <form> tags and kept the inner <form> tags located towards the end of the "echo" repeats and inserted the hidden field under that. So now it looks like        

          echo         '<form action="compose.php" method="POST">';
          echo            '<input type="hidden" name="id" value="'.$row['id'].'" />';
          echo            '<input type="submit" name="message" id="message" value="Message">';
          echo         '</form>';

With the receiving page looking like this:

<?php
      if(isset($_POST['id']) && is_numeric($_POST['id'])) {
    // run query to get first_name where the submitted record id matches
    $toCD = "SELECT `first_name` FROM `users` WHERE `id` =" .intval($id);
    $toST = $con->query($toCD);
    // make sure a row was return
    if($toST->num_rows === 1) {
        $row = $toST->fetch_assoc();
        echo  "<div class = 'prep_stmt'>Your message to".$_row['first_name']."...</div>";
    }
    else {
        echo "<div class = 'prep_error'>Sorry, contact could not go through. Try again later.</div>";
        // record id does not exist. Output error message
    }
}
      ?>

Your explanations are really helpful, by the way. I am starting to realize the logic behind the networking required and what I am up against.

I realized I didn't update my code previously. Here is what I have so far:

 

on list.php:

<?php
if ($searchST) {
while ($row = $searchST->fetch_assoc()) {
echo '<div class="z">';
echo '<div class="x">';
echo '<div class="y">';
echo '<div class="text_info">';
echo "<div id='input_titles'>C1</div><textarea readonly name='c1' id='a' rows='3' cols='54' maxlength='162' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c1"]."</textarea><br />";
echo "<div id='input_titles'>C2</div><textarea readonly name='c2' id='a' rows='3' cols='54' maxlength='162' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c2"]."</textarea><br />";
echo "<div id='input_titles'>C3</div><textarea readonly name='c3' id='a' rows='15' cols='54' maxlength='810' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c3"]."</textarea><br />";
echo "<div id='input_titles'>C4</div><textarea readonly name='c4' id='a' rows='2' cols='54' maxlength='108' onCopy='return false' onDrag='return false' onDrop='return false' onPaste='return false' autocomplete='off'>".$row["c4"]."</textarea>";
echo '</div>';
echo '<div class="visual_info">';
echo '<div class="p_pic_image">';
echo "<img src='".$row["pic"]."' id='p_pic'> ";
echo '</div>';
echo '<div class="country_and_name">';
echo "<textarea readonly name='country' id='country' rows='1' cols='14'>".$row["country"]."</textarea>";
echo "&nbsp".$row["first_name"];
echo '</div>';
echo '</div>';
echo '<form action="compose.php" method="POST">';
echo '<input type="hidden" name="id" value="'.$row['id'].'" />'; //the insert
echo '<input type="submit" name="message" id="message" value="Message">';
echo '</form>';
echo '</div>';
echo '</div>';
echo '</div>';

if (isset($_POST['message'])) {
$carry = "SELECT `first_name` FROM `users`";
$carryST = $con->query($carry);
if($carryST) {
while ($row = $carryST->fetch_assoc()) {
$_SESSION['to_name'] = $row["first_name"];
$_SESSION['to_id'] = $row["id"];

}
}

$carryST->close();
header("location: compose.php");
exit();
}
echo '</form>';

}

}
$searchST->close();
} else {

}

And on the receiving end, compose.php:

 

  
<?php
      if(isset($_POST['id']) && is_numeric($_POST['id'])) {
    // run query to get first_name where the submitted record id matches
    //  $toCD = "SELECT `first_name` FROM `users` WHERE `id` =" .intval($id);
    $toST = $con->query('SELECT first_name FROM users WHERE id = ' . intval($id));
    // make sure a row was return
    if($toST->num_rows === 1) {
        $row = $toST->fetch_assoc();
        echo  "<div class = 'prep_stmt'>Your message to".$_row['first_name']."...</div>";
    }
    else {
      // record id does not exist. Output error message
        echo "<div class = 'prep_error'>Sorry, contact could not go through. Try again later.</div>";
    }
}
      ?>

 

What is the output of this in compose.php

var_dump($_POST);

 

By doing that, I get the following:

Sorry, contact could not go through. Try again later.
array(2) { ["id"]=>string(1)"2"["message"]=>string(7)"Message"}

I think this maybe due to the way conditions are read on the receiving end:

if(isset($_POST['id']) && is_numeric($_POST['id'])) {

Though the confusing part is that the ["id"] being outputted is the correct id position of the user I was trying to get, so I don't know why it isn't outputting this part:

if(isset($_POST['id']) && is_numeric($_POST['id'])) {
    // run query to get first_name where the submitted record id matches
    //  $toCD = "SELECT `first_name` FROM `users` WHERE `id` =" .intval($id);
    $toST = $con->query('SELECT first_name FROM users WHERE id = ' . intval($id));
    // make sure a row was return
    if($toST->num_rows === 1) {
        $row = $toST->fetch_assoc();
        echo  "<div class = 'prep_stmt'>Your message to".$_row['first_name']."...</div>";
    }

I tried it with another user, and I get the same results. The id stored in the array is correct, but it isn't executing the right conditions. ;D  :confused:

Edited by innovatio

Ok so it looks like the query is failing. Apply error checking to your query

    $toST = $con->query('SELECT first_name FROM users WHERE id = ' . intval($id));
    // make sure query did not retun error (FALSE)
    if($toST)
    {
        // make sure a row was return
        if($toST->num_rows === 1) 
        {
            $row = $toST->fetch_assoc();
            echo  "<div class = 'prep_stmt'>Your message to".$_row['first_name']."...</div>";
        }
        else
        {
            // record id does not exist. Output error message
            echo "<div class = 'prep_error'>Sorry, contact could not go through. Try again later.</div>";
        }
    }
    // get error from query
    else
    {
        trigger_error('Unable to query users table: ' . $con->error);
    }

 

Ok so it looks like the query is failing. Apply error checking to your query

    $toST = $con->query('SELECT first_name FROM users WHERE id = ' . intval($id));
    // make sure query did not retun error (FALSE)
    if($toST)
    {
        // make sure a row was return
        if($toST->num_rows === 1) 
        {
            $row = $toST->fetch_assoc();
            echo  "<div class = 'prep_stmt'>Your message to".$_row['first_name']."...</div>";
        }
        else
        {
            // record id does not exist. Output error message
            echo "<div class = 'prep_error'>Sorry, contact could not go through. Try again later.</div>";
        }
    }
    // get error from query
    else
    {
        trigger_error('Unable to query users table: ' . $con->error);
    }

 

I did so but nothing has changed in terms of the output.

Durp! I messed up earlier

 

 intval($id)  should of been  intval($_POST['id'])  

 

Also $_row should be $row (no underscore)

 

Dear sir, you have brought sunlight unto my problems. It is solved! :pirate: I am still new to php and have been wracking my brain over this for weeks, and you, my deux ex machina, have saved me. Thank you so much!

 

So now I can query anything relating to user #2 by referencing to intval($_POST['id']), correct?

 

Merci beaucoup, monsieur  :-*  :happy-04: .

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.