I have a form that submits images and their titles. It is set up to check for errors via PHP validations on the image title form input elements and output any errors inside each image component (i.e. the instance in the while loop that represents a certain image). This all works OK.
What I would like to do is have it so that when one or more title is filled out correctly, but there are errors on one or more other titles, the $_POST value of the incorrect input is echoed out in the input element so the user doesn't have to re-type it. This has been easy to do on other forms on the site because there is no loop involved, e.g. on a sign up form etc. On a singular instance I would just do <?php echo $image_title; ?> inside the HTML value attribute, which is set referencing $image_title = $_POST['image-title'];]
So my question is, how do I have it so the $image_title $_POST value instances that pass the validations are outputted in their respective <input> elements, when other instances of the $image_title variable fail. If all the checks pass and there are no errors the form is then processed with PDO statements. The form submission button is placed outside of the main loop so all images are processed in one go when all the information is correct. I have a hidden input element that outputs the database image ID for each image, which can be used as a key in a foreach loop of some type. The problem of course being I can't get a foreach loop to work as I would like.
NOTE: To make the code simpler I've removed all the code relating to the outputting the images themselves.
<?php
if(isset($_POST['upload-submit'])) {
$image_title = $_POST['image-title'];
$image_id = $_POST['image-id']; // value attribute from hidden form element
// checks for errors that are later outputted on each image component
forEach($image_title as $index => $title) {
$id=$_POST['image-id'][ $index ];
if(empty(trim($title))){
$error[$id] = "Title cannot be empty";
}
}
if (!isset($error)) {
try {
// update MySQL database with PDO statements
header("Location: upload-details.php?username={$username}");
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
}
?>
<form method="post" enctype="multipart/form-data">
<!-- IMAGE DETAILS COMPONENT - START -->
<?php
$user_id = $_SESSION['logged_in'];
$stmt = $connection->prepare("SELECT * FROM lj_imageposts WHERE user_id = :user_id");
$stmt->execute([
':user_id' => $user_id
]);
while ($row = $stmt->fetch()) {
$db_image_id = htmlspecialchars($row['image_id']);
$db_image_title = htmlspecialchars($row['image_title']);
?>
<div >
<?php
// output error messages from the validation above
if(isset($error)) {
foreach($error as $element_id => $msg) {
if($element_id == $id) {
echo "<p>** ERROR: {$msg}</p>";
}
}
}
?>
<div >
<div >
<!-- ** THIS IS THE INPUT ELEMENT WHERE I WOULD LIKE THE TITLE OUTPUTTED IF IT DOESN'T FAIL THE VALIDATION ** -->
<input value="<?php echo $image_title; ?>" type="text" name="image-title[]">
</div>
<div >
<input type="hidden" name="image-id[]" value="<?php echo $db_image_id; ?>">
</div>
</div>
</div>
<?php
// prevents errors when title input is empty
$image_title = "";
} ?> <!-- // end of while loop -->
<!-- submit form button is outside of the loop so that it submits all of the images inside the loop in on go -->
<button type="submit" name="upload-submit">COMPLETE UPLOAD</button>
</form>
CodePudding user response:
i think this is what you want:
<input value="<?php echo htmlentities($image_title); ?>" type="text" name="image-title[<?php echo $db_image_id; ?>]">
foreach ($_POST['image-title'] as $key => $value) {
$stmt->execute([
':image_id' => $key,
':image_title' => $value
]);
}
CodePudding user response:
You need to construct the loops with the common denominator being the common data -- in this case the reference ID. You need to use the reference ID as an array Key in the <input> fields and in the corresponding PHP saves.
Something very roughly like this:
foreach($imageRow as $dataRow){
// $db_image_id would be $dataRow['id'];
// $image_title would be $dataRow['imageTitle'];
<div >
<div >
<!-- ** THIS IS THE INPUT ELEMENT WHERE I WOULD LIKE THE TITLE OUTPUTTED IF IT DOESN'T FAIL THE VALIDATION ** -->
<input name="image-title[<?php echo $dataRow['id'];?>]"> value="<?php echo $dataRow['imageTitle']; ?>" type="text"
</div>
</div>
}
Then your corresponding PHP POST data would look like this:
$_POST['image-title'][1] = "description image title 1";
$_POST['image-title'][3] = "image title for 3";
You can then process this data with another foreach loop but this time preserve the key as this is the ID key that you need to save the data or do whatever you need to do...
foreach($_POST['image-title'] as $postKey => $postData){
/***
* SIMPLE EXAMPLE only:
***/
$array = [];
$array['id'] = $postKey; // 1
$array['title'] = $postData; // description image title 1
// Data is saved to the databased based on corresponding reference id key.
$database->update('update table set image_title = :title WHERE image_id = :id , $array );
}
