Hello.

I am trying to create an update form that will update values in a MySQL database.

The forms are generated for each different row in the database through a while loop (ie whilst there is another row, make a new form on the page).

However, I cannot get it to update to the databse correctly, having tried numerous different configurations.

I did try making it so that each aspect of the form had a name such as Title[$counter], but this did not work at all. I was told setting id tags on the inputs might help, but I'm not sure how that would work

The code below updates every field in the database, probably as each form on the page has the same name and contents

<?php $db = new mysqli ('localhost','***','***','***');//connect to db
				$results = $db->query("select * from images");
				while ($row = $results->fetch_assoc()){
					$counter=$row['pkey'];?>
   <form name="newad" method="post" enctype="multipart/form-data"  action="">
      <table width="456">
        <tr>
          <td>Title: </td>
          <td><input type="text" name="Title"  value="<?php echo $row['title']?>" ></td>
             <td><input type="submit" name="Submit" /></td></tr>
     </table>
      </form>
      <?php 		
  if(isset($_POST['Submit'])) 
 {$title=$_POST['Title']; 
$results4 = $db->query("UPDATE images SET title='$title' WHERE pkey='$counter'");
}}	 
$db->close(); ?>

Closing the while loop before the if state ment causes the database to update only the last row. There are other fields to update in the databse, but I'd like to get one working first.
Any help would be appreciated.

Thanks

Dani AI

Generated

Good catch by — the page needs to process the POST first, then re-query the DB for rendering. The symptom you saw (submit, but the field still shows the old value until a manual refresh) happens because the script was building the HTML from the old SELECT results before the UPDATE ran. Also avoid doing updates inside the same while-loop that prints forms; relying on a loop variable like $counter at render-time can point at the wrong row.

A simple, robust pattern: handle the POST at the top, run the UPDATE with a prepared statement, then redirect (Post/Redirect/Get) so the page reloads and shows fresh data. Example pattern:

<?php
$db = new mysqli(...);

// process update first
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['pkey'], $_POST['title'])) {
  $stmt = $db->prepare("UPDATE images SET title = ? WHERE pkey = ?");
  $stmt->bind_param('si', $_POST['title'], $_POST['pkey']);
  $stmt->execute();
  $stmt->close();
  header('Location: ' . $_SERVER['REQUEST_URI']); // PRG: shows updated data and avoids double-post
  exit;
}

// then SELECT and render forms...
?>

If you want instant UI updates without a full reload, send the update via Ajax and update the input value in the DOM on success (or replace the row HTML). For bulk edits, use a single form with inputs named as an array, e.g. title[123], then loop over $_POST['title'] server-side and update each pkey.

Final tips: always use prepared statements to prevent SQL injection; escape output into value="..." with htmlspecialchars($row['title'], ENT_QUOTES) to avoid broken HTML/XSS; give each form a unique id; and check $db->error/$stmt->error while debugging. After you move the update logic to the top and use the redirect trick, the new title should appear immediately without a manual refresh.

Recommended Answers

All 3 Replies

I think I understand what you're trying to do, and the code below should work. But it's really not very clean HTML, nor is it very nice from a UI standpoint. Personally I would try to make all of the database entries go into a select box where I would choose the one I wished to edit rather than listing them all as their own forms.

<?php
if(isset($_POST['Submit']))
{
$counter = $_POST['counter'];
$title=$_POST['Title'];
$results4 = $db->query("UPDATE images SET title='$title' WHERE pkey='$counter'");
}

$db = new mysqli ('localhost','***','***','***');//connect to db
$results = $db->query("select * from images");

while ($row = $results->fetch_assoc())
{

$counter=$row['pkey']; //added this as an id and hidden field so you know what is being submitted.

$form.= '<form name="newad" id="newad'.$counter.'"  method="post" enctype="multipart/form-data" action="">
<table width="456">
<tr>
<td>Title: </td>
<td><input type="text" name="Title" value="'.$row['title'].'" ></td>
<input type="hidden" name="counter" id="c'.$counter.'" value="'.$counter.'" />
<td><input type="submit" name="Submit" /></td></tr>
</table>
</form>';
}

echo $form;

$db->close();
?>

Thanks, hat did the trick.

I am going to have a selection box at the top so that it only displays a small section of all the entries so the page is not dominated by forms.

One small thing, not too major if it can't be fixed, but after clicking the submit button the field returns to it's old value, and the page needs to refresh to see the new value. Is there any way other than auto refreshing the page for this?

I think these lines should be at the top:

$db = new mysqli ('localhost','***','***','***');//connect to db
$results = $db->query("select * from images");

Let me know if that helps

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.