innovatio Posted September 6, 2015 Share Posted September 6, 2015 (edited) 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: 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: 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 " ".$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 September 6, 2015 by Ch0cu3r Quote Link to comment Share on other sites More sharing options...
Ch0cu3r Posted September 6, 2015 Share Posted September 6, 2015 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 } } Quote Link to comment Share on other sites More sharing options...
Barand Posted September 6, 2015 Share Posted September 6, 2015 You have two <form> tags, one at the start of the loop and another just before the submit buttom. Suggest you put the hidden id field after the second and remove the first. Quote Link to comment Share on other sites More sharing options...
innovatio Posted September 6, 2015 Author Share Posted September 6, 2015 (edited) 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 " ".$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> 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 September 6, 2015 by innovatio Quote Link to comment Share on other sites More sharing options...
Ch0cu3r Posted September 7, 2015 Share Posted September 7, 2015 (edited) 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 September 7, 2015 by Ch0cu3r Quote Link to comment Share on other sites More sharing options...
Barand Posted September 7, 2015 Share Posted September 7, 2015 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 ... Quote Link to comment Share on other sites More sharing options...
innovatio Posted September 7, 2015 Author Share Posted September 7, 2015 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. Quote Link to comment Share on other sites More sharing options...
Ch0cu3r Posted September 7, 2015 Share Posted September 7, 2015 What is the output of this in compose.php var_dump($_POST); Quote Link to comment Share on other sites More sharing options...
innovatio Posted September 7, 2015 Author Share Posted September 7, 2015 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 " ".$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>"; } } ?> Quote Link to comment Share on other sites More sharing options...
innovatio Posted September 7, 2015 Author Share Posted September 7, 2015 (edited) 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. Edited September 7, 2015 by innovatio Quote Link to comment Share on other sites More sharing options...
Ch0cu3r Posted September 7, 2015 Share Posted September 7, 2015 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); } Quote Link to comment Share on other sites More sharing options...
innovatio Posted September 7, 2015 Author Share Posted September 7, 2015 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. Quote Link to comment Share on other sites More sharing options...
Solution Ch0cu3r Posted September 7, 2015 Solution Share Posted September 7, 2015 Durp! I messed up earlier intval($id) should of been intval($_POST['id']) Also $_row should be $row (no underscore) Quote Link to comment Share on other sites More sharing options...
innovatio Posted September 7, 2015 Author Share Posted September 7, 2015 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! 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 . Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.