The Situation
Having a form that includes image components generated from a MySQL database with PHP, I've implemented javascript fetch()
functionality on different pages of the website to enhance user experience. However, in cases where the functionality is specific to individual forms, such as having multiple components within a single <form>
, I encounter challenges.
Utilizing a while
loop to output the components inside the form allows for multiple images to be uploaded in a single submission. The issue arises when attempting to apply the javascript fetch()
function for deleting an image component without requiring a full page reload.
I attempted modifying the javascript code originally designed for each image being in its own form, which is not practical from a user experience perspective. My approach involved selecting the image component within the form (i.e., .upload-details-component
) using a forEach
loop, but this method did not yield the desired results.
A visual representation of the grid can be seen below, with the 'delete' button signifying the delete action:
[![enter image description here][1]][1]
HTML snippet:
<form class="upload-details-form upload-form-js" method="post" enctype="multipart/form-data">
<div class="image-component-wrapper">
<!-- image-component-wrapper start -->
<?php
$user_id = $db_id; // database id imported from header.php
$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']); ?>
<div class="upload-details-component">
<img src="image.jpg" />
<div class="form-row">
<input id="title-id-<?php echo $db_image_id; ?>" value="Image Title" type="text" name="image-title[]" placeholder="Image Title" />
</div>
<div class="form-row">
<!-- BUTTON THAT DELETES AND IMAGE -->
<button name="upload-details-delete" value="<?php echo $db_image_id; ?>" style="background: #cc1f1f;" class="remove-image">DELETE</button>
<input type="hidden" name="image-id[]" value="<?php echo $db_image_id; ?>" />
</div>
</div>
<?php } ?>
</div>
<!-- image-component-wrapper end -->
<div class="form-row">
<button id="upload-submit" type="submit" name="upload-submit">COMPLETE UPLOADS</button>
</div>
</form>
Javascript snippet:
// ---- FETCH
var forms = document.querySelectorAll(".upload-form-js"),
// image component
uploadDetailsComponent = document.querySelectorAll(".upload-details-component"),
// delete button
deleteButton = document.querySelectorAll(".remove-image");
// URL details
var myURL = new URL(window.location.href),
pagePath = myURL.pathname;
if (uploadDetailsComponent) {
uploadDetailsComponent.forEach((item) => {
deleteButton.forEach((button) => {
button.addEventListener("click", (e) => (item._button = button)); //store this button in the form element
});
item.addEventListener("submit", function (evt, btn) {
evt.preventDefault();
var formData = new FormData(this);
if (this._button) {
// submitted by a button?
formData.set(this._button.name, this._button.value);
// delete this._button; //this only needed if form can be submitted without submit button (aka submitted by javascript)
}
fetch(pagePath, {
method: "post",
body: formData,
})
.then(function (response) {
return response.text();
})
.catch(function (error) {
console.error(error);
});
item.remove(); // removes component from HTML
});
});
} // end of if (upload-details-component)