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' functionbody {
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"