Delete An Image() Object From Memory On Click Event Of Sibling Element — Javascript
I have an image previewer that uses the JavaScript Image() object to preview images prior to them being processed with PHP. I have a div that contains an 'x' SVG graphic that is ta
Solution 1:
Problem:
You are not updating fileUploader.files
when you add/remove
an item.
Solution
Every time you drop/remove
a file you need to update the fileUploader input. The first step is to create a function to handle the FileList object and change only two lines of your code:
//--> to create a FileListfunction getFileListItems (files) {
var transferObject = new ClipboardEvent("").clipboardData || new DataTransfer()
for (var i = 0; i<files.length; i++) transferObject.items.add(files[i])
return transferObject.files;
}
Add files during the drop event:
//--> Updating files during drop event
fileUploader.files = getFileListItems([...fileUploader.files, ...evt.dataTransfer.files]);
Removing a file:
fileUploader.files = getFileListItems([...fileUploader.files].filter(f => file!==f));
See a complete working example:
const dropZone = document.getElementById("drop-zone"),
showSelectedImages = document.getElementById("show-selected-images"),
fileUploader = document.getElementById("standard-upload-files");
dropZone.addEventListener("click", (evt) => {
// assigns the dropzone to the hidden input element so when you click 'select files' it brings up a file picker window
fileUploader.click();
});
// Prevent browser default when draging over
dropZone.addEventListener("dragover", (evt) => {
evt.preventDefault();
});
fileUploader.addEventListener("change", (evt) => {
// this function is further down but declared here and shows a thumbnail of the image
[...fileUploader.files].forEach(updateThumbnail);
});
functiongetFileListItems(files) {
var transferObject = newClipboardEvent("").clipboardData || newDataTransfer()
for (var i = 0; i < files.length; i++) transferObject.items.add(files[i])
return transferObject.files;
}
dropZone.addEventListener("drop", (evt) => {
evt.preventDefault();
// assign dropped files to the hidden input elementif (evt.dataTransfer.files.length) {
fileUploader.files = getFileListItems([...fileUploader.files, ...evt.dataTransfer.files]);
}
// function is declared here but written further down
[...evt.dataTransfer.files].forEach(updateThumbnail);
});
// updateThumbnail function that needs to be able to handle multiple filesfunctionupdateThumbnail(file) {
if (file.type.startsWith("image/")) {
let uploadImageWrapper = document.createElement("article"),
removeImage = document.createElement("div"),
thumbnailElement = newImage();
// 'x' that deletes the image
removeImage.classList.add("remove-image");
removeImage.innerHTML =
'<svg id="remove-x" viewBox="0 0 150 150"><path fill="#000" d="M147.23,133.89a9.43,9.43,0,1,1-13.33,13.34L75,88.34,16.1,147.23A9.43,9.43,0,1,1,2.76,133.89L61.66,75,2.76,16.09A9.43,9.43,0,0,1,16.1,2.77L75,61.66,133.9,2.77a9.42,9.42,0,1,1,13.33,13.32L88.33,75Z"/></svg>';
// image thumbnail
thumbnailElement.classList.add("drop-zone__thumb");
thumbnailElement.src = URL.createObjectURL(file);
// appending elements
showSelectedImages.append(uploadImageWrapper); // <article> element
uploadImageWrapper.append(removeImage); // 'x' to delete
uploadImageWrapper.append(thumbnailElement); // image thumbnail// Delete images
removeImage.addEventListener("click", (evt) => {
if (evt.target) {
var deleteImage = removeImage.parentElement;
deleteImage.remove();
fileUploader.files = getFileListItems([...fileUploader.files].filter(f => file !== f));
}
});
}
} // end of 'updateThumbnail' function
body {
margin: 0;
display: flex;
justify-content: center;
width: 100%;
}
form {
width: 30%;
}
#drop-zone {
border: 1px dashed;
width: 100%;
padding: 1rem;
margin-bottom: 1rem;
}
.select-files {
text-decoration: underline;
cursor: pointer;
}
/* image that is preview prior to form submit*/.drop-zone__thumb {
width: 200px;
height: auto;
display: block;
}
#remove-x {
width: 1rem;
height: 1rem;
}
#submit-images {
margin: 1rem0;
}
#show-selected-images {
display: flex;
}
<formid="upload-images-form"enctype="multipart/form-data"method="post"><h1>Upload Your Images</h1><divid="drop-zone"class="drop-zone flex"><pclass="td text-center">DRAG AND DROP IMAGES HERE</p><pclass="td text-center"style="margin: 0">Or</p><pclass="tl text-center select-files text-bold pointer">Select Files</p></div><inputid="standard-upload-files"style="display:none"style="min-width: 100%"type="file"name="standard-upload-files[]"multiple><inputtype="submit"name="submit-images"id="submit-images"value="SUBMIT IMAGES"><divid="show-selected-images"></div></form>
Working example
Solution 2:
This is because when a form submitted, it doesn't submit every HTML element in the form, but only values of input
, textarea
, pressed button
and some others that have name
attribute.
So what you need is clear the file input
field too:
const showSelectedImages = document.getElementById("preview");
const input = document.getElementById("test");
functionupdateThumbnail(file) {
if (file.type.startsWith("image/")) {
// image and 'x' to delete wrapper const uploadImageWrapper = document.createElement('article')
// div that holds the 'x' to deleteconst removeImage = document.createElement('div')
// image preview element
thumbnailElement = newImage()
// 'x' that deletes the image
removeImage.classList.add("remove-image")
removeImage.innerHTML = 'x'// image thumbnail
thumbnailElement.classList.add("drop-zone__thumb")
thumbnailElement.src = URL.createObjectURL(file)
// appending elements
showSelectedImages.append(uploadImageWrapper) // <article> element
uploadImageWrapper.append(removeImage) // 'x' to delete
uploadImageWrapper.append(thumbnailElement) // image thumbnail// Delete Images when the 'x' div is clicked
removeImage.addEventListener('click', (evt) => {
if (evt.target) {
var deleteImage = removeImage.parentElement
deleteImage.remove();
/* for single file input is enough clear value property */// input.value = null;/* for multiple files input we'll need recreate new files list excluding deleted file */const dt = newDataTransfer();
for (let f of input.files) {
if (f !== file)
dt.items.add(f);
}
input.files = dt.files;
}
})
}
}
functionupdateThumbnails(files) {
showSelectedImages.innerHTML = ""; //remove all previous previewsfor (let f of files)
updateThumbnail(f);
}
functionshowform(form) {
const list = {};
for (let i of [...newFormData(form).entries()]) {
const key = i[0].match(/^([^\[]+)\[\]$/);
if (key) {
if (!list[key[1]])
list[key[1]] = [];
list[key[1]][list[key[1]].length] = i[1];
} else
list[i[0]] = i[1];
}
console.log(list)
returnfalse;
}
.remove-image {
cursor: pointer;
}
article {
display: inline-block;
}
<formtype="post"onsubmit="return showform(this);"><inputtype="hidden"name="myHiddenInput"value="blah"><inputtype="file"name="test[]"id="test"oninput="updateThumbnails(this.files)"multiple><spanid="preview"></span><buttontype="submit">submit</button></form>
Post a Comment for "Delete An Image() Object From Memory On Click Event Of Sibling Element — Javascript"