I have a html form which is used for uploading file. I can preview images and have delete option from preview itself. However, it isn't deleted from image list which used for uploading the image into server. Please help me to delete the selected image from list
Javascript code:
$(document).ready(function() {
if (window.File && window.FileList && window.FileReader) {
$("#files").on("change", function(e) {
var files = e.target.files,
filesLength = files.length;
for (var i = 0; i < filesLength; i++) {
var f = files[i]
var fileReader = new FileReader();
fileReader.onload = (function(e) {
var file = e.target;
$("<span class=\"pip\">" +
"<img class=\"imageThumb\" src=\"" +
e.target.result + "\" title=\"" + file.name + "\"/>" +
"<br/><span class=\"remove\">Remove image</span>" +
"</span>").insertAfter("#files");
$(".remove").click(function(){
$(this).parent(".pip").remove();
});
});
fileReader.readAsDataURL(f);
}
});
} else{
alert("Your browser doesn't support to File API")
}
});
Change the remove action to this, this will remove all the files
$(".remove").click(function(){
$(this).parent(".pip").remove()
$("#files").val('') // this is new
})
you can't remove only one file as e.target.files is read-only.
Related
I made a file uploader that handles images, but it doesn't work well with files.
For example: if I upload 3 xlsx/word or any files, these will have the same name for each.
My code is here:
<form>
<input id="files" type="file" multiple="multiple">
<div id="result"></div>
</form>
function handleFileSelect(event) {
if (window.File && window.FileList && window.FileReader) {
var files = Array.from(event.target.files);
var output = document.getElementById("result");
output.innerHTML = '';
console.log(files);
for (var i = 0; i < files.length; i++) {
var file = files[i];
if(file.type.match('.php')){
alert('ERROR');
continue;
}
var picReader = new FileReader();
picReader.addEventListener("load", function (event) {
var picFile = event.target;
var div = document.createElement("div");
div.className = "col-6 col-sm-4 p-1";
if (file.type.match('image')) {
div.innerHTML = "<img src='" + picFile.result + "'" + "title='" + file.name + "'/>";
}else{
div.innerHTML = "<div class='upload-thumb'>" + file.name + "</div>";
}
output.insertBefore(div, null);
});
picReader.readAsDataURL(file);
}
} else {
console.log("Your browser does not support File API");
}
}
Link:
https://jsfiddle.net/laszlooo/7c1Lv5x2/
Thank You!
Problem you have is you have the infamous for loop bug. Where the reference to i updates as your loop executes. You can either use let instead of var or break out the part you read the file into a function so you do not have the issue.
function readFile(file, output) {
var picReader = new FileReader();
picReader.addEventListener("load", function(event) {
var picFile = event.target;
var div = document.createElement("div");
div.className = "col-6 col-sm-4 p-1";
if (file.type.match('image')) {
div.innerHTML = "<img src='" + picFile.result + "'" + "title='" + file.name + "'/>";
} else {
div.innerHTML = "<div class='upload-thumb'>" + file.name + "</div>";
}
output.insertBefore(div, null);
});
picReader.readAsDataURL(file);
}
function handleFileSelect(event) {
if (window.File && window.FileList && window.FileReader) {
var files = Array.from(event.target.files);
var output = document.getElementById("result");
output.innerHTML = '';
console.log(files);
for (var i = 0; i < files.length; i++) { // <-- where the problem begins
var file = files[i]; // <-- this is your problem with the reference
if (file.type.match('.php')) {
alert('ERROR');
continue;
}
readFile(file, output) // <-- using a function gets around the reference issue
}
} else {
console.log("Your browser does not support File API");
}
}
document.querySelector("input").addEventListener("change", handleFileSelect)
<form>
<input id="files" type="file" multiple="multiple">
<div id="result"></div>
</form>
I manage to generate the thumbnail via the script below
$('input#fileupload').on('change', function() {
for (var i = 0; i < this.files.length; i++) {
var fr = new FileReader();
var name = this.files.item(i).name;
fr.onload = function(e) {
$('#thumbs ul').append('<li><img src="' + e.target.result + '"><span>' + name[i] + '</span></li>');
};
fr.readAsDataURL(this.files[i]);
}
});
But unable to insert the file name into the appended <li></li> element
The issue is because you're using files.item(i).name which is invalid. You instead need to access the files array by index, then get the name property.
Also note that when you append the variable in to the span, you can use name directly, not name[i].
Finally, you'll need to use a closure to maintain the scope of the current file when in the onload event handler. Try this:
$('input#fileupload').on('change', function() {
for (var i = 0; i < this.files.length; i++) {
(function(file) {
var name = file.name;
var fr = new FileReader();
fr.onload = function(e) {
$('#thumbs ul').append('<li><img src="' + e.target.result + '"><span>' + name + '</span></li>');
};
fr.readAsDataURL(file);
})(this.files[i])
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="fileupload" multiple="true" />
<div id="thumbs">
<ul></ul>
</div>
I'm trying to add preview and delete option before uploading multiple images, this is what I found:
$(document).ready(function() {
if (window.File && window.FileList && window.FileReader) {
$("#files").on("change", function(e) {
var files = e.target.files,
filesLength = files.length;
for (var i = 0; i < filesLength; i++) {
var f = files[i]
var fileReader = new FileReader();
fileReader.onload = (function(e) {
var file = e.target;
$("<span class=\"pip\">" +
"<img class=\"imageThumb\" src=\"" + e.target.result + "\" title=\"" + file.name + "\"/>" +
"<br/><span class=\"remove\">Remove image</span>" +
"</span>").insertAfter("#files");
$(".remove").click(function(){
$(this).parent(".pip").remove();
});
});
fileReader.readAsDataURL(f);
}
});
} else {
alert("Your browser doesn't support to File API")
}
});
But while uploading all images are getting uploaded, how to resolve this? I'm using php.
Ok, i'm create example that solved your problem:
Your HTML
<form method="post" id="sendForm">
<input type="file" id="files" multiple>
<input type="submit">
</form>
Your JS
$(document).ready(function() {
if (window.File && window.FileList && window.FileReader) {
// Array which stores all selected images
var sendData = [];
$("#files").on("change", function(e) {
var files = e.target.files,
filesLength = files.length;
for (var i = 0; i < filesLength; i++) {
var f = files[i]
var fileReader = new FileReader();
fileReader.onload = (function(e) {
var file = e.target;
$("<span class=\"pip\">" +
"<img class=\"imageThumb\" src=\"" + e.target.result + "\" title=\"" + file.name + "\"/>" +
"<br/><span class=\"remove\">Remove image</span>" +
"</span>").insertAfter("#files");
// Add all images to array
sendData.push({file: file, url: e.target.result});
$(".remove").click(function() {
var self = $(this).parent().children();
sendData.map(function(value, currentIndex, data) {
// Remove only image which removed from preview
if (self[0].currentSrc === value.url) {
sendData.splice(currentIndex, 1);
}
});
$(this).parent().remove();
});
$("#sendForm").submit(function(e) {
// Finally post all data to your PHP url that
$.post("your/php/url", sendData);
});
});
fileReader.readAsDataURL(f);
}
});
} else {
alert("Your browser doesn't support to File API")
}
});
I'm currently testing out a piece of code by user OGiS0. It is a javascript code that uploads images. How would I make it so that every time an image gets uploaded, it gets a new ID so I can drag and drop it without interference.
window.onload = function(){
//Check File API support
if(window.File && window.FileList && window.FileReader)
{
var filesInput = document.getElementById("files");
filesInput.addEventListener("change", function(event){
var files = event.target.files; //FileList object
var output = document.getElementById("result");
for(var i = 0; i< files.length; i++)
{
var file = files[i];
//Only pics
if(!file.type.match('image'))
continue;
var picReader = new FileReader();
picReader.addEventListener("load",function(event){
var picFile = event.target;
var div = document.createElement("div");
div.innerHTML = "<img id='thumbnail' draggable='true' ondragstart='drag(event)' src='" + picFile.result + "'" +
"title='" + picFile.name + "'/>";
output.insertBefore(div,null);
});
//Read the image
picReader.readAsDataURL(file);
}
});
}
else
{
console.log("Your browser does not support File API");
}
}
Fiddle to show how it works: http://jsfiddle.net/Yvgc2/1563/
Currently, all the images have the same id when uploaded so drag and drop cannot occur.
Quick and dirty: use a global variable (window.thumbId).
The reason why you shouldn't use the i variable is, that it will restart each time you upload picture(s).
window.thumbId will work regardless how many times and how many images you upload. You'll get ids like thumbnail1, thumbnail2, etc:
window.thumbId = (window.thumbId || 0)+1;
div.innerHTML = "<img id='thumbnail"+window.thumbId+"' draggable='true' ondragstart='drag(event)' src='" + picFile.result + "'" +
"title='" + picFile.name + "'/>";
If the files get stored in a DB, you can use the db index as a unique id, get last index and +1 on each new item.
If not you can use the loops index and replace this line
div.innerHTML = "<img id='"+i+"' draggable='true' ondragstart='drag(event)' src='" + picFile.result + "'" +
"title='" + picFile.name + "'/>";
i am trying to create multiple image uploader with delete option,till now i am able to select unique multiple files but i want to have a delete option .for that i have to generate an id for each image to delete it before uploading :
window.onload = function(){
//Check File API support
if(window.File && window.FileList && window.FileReader)
{
var filesInput = document.getElementById("files");
filesInput.addEventListener("change", function(event){
var files = event.target.files; //FileList object
var dive = $(".overview").find('img').length;
var output = document.getElementById("result");
// console.log(files);
for(var i = 0; i< files.length; i++)
{
var file = files[i];
//Only pics
if(!file.type.match('image'))
continue;
$(".overview .imgdivcon").each(function(){
var its =$(this).children().eq(1).attr("title");
if(its == file.name ){
throw alert("already exits") ;
}
});
var divn = i+dive+1;
var picReader = new FileReader();
console.log(divn);
picReader.addEventListener("load",function(event){
var picFile = event.target;
var div = document.createElement("div");
div.className="imgdivcon";
div.innerHTML = "<p onclick='sliceimg("+divn+")' class='close' name='"+i+"' id='cl'>x</p><img width='150' height='150' class='thumbnail' src='" + picFile.result + "'" +
"title='" + file.name + "'/>";
output.insertBefore(div,null);
});
//Read the image
picReader.readAsDataURL(file);
}
});
when i'm selecting single image its generating unique id for each image ,but when i'm selecting multiple images it's giving total images count for each image but not a unique count.
here is my js fiddle link http://jsfiddle.net/aerfan/CdgUV/ little help wil be aprreciated .
You got wrong unique id (should be the order of image instead of total count) when you select multiple images because the "divn" variable will be the total count of images when the picReader load event handler being triggered.
Closure will add local variable to its scope when function was created. The outer for loop finished before file reader load callback being executed and divn will be the total count of images.
for(var i = 0; i< files.length; i++)
{
......
var divn = i+dive+1; //this variable will be added to callback closure
.......
picReader.addEventListener("load",function(event){
........
//divn is always the total count of images
div.innerHTML = "<p onclick='sliceimg("+divn+")' class='close' name='"+i+"' id='cl'>x</p><img width='150' height='150' class='thumbnail' src='" + picFile.result + "'" +
"title='" + file.name + "'/>";
output.insertBefore(div,null);
});
}
To solve this problem, you could try to use currying technique. Let's update the picReader load event callback:
picReader.addEventListener("load",(function(divn){
return function(event){
var picFile = event.target;
var div = document.createElement("div");
div.className="imgdivcon";
div.innerHTML = "<p onclick='sliceimg("+divn+")' class='close' name='"+i+"' id='cl'>x</p><img width='150' height='150' class='thumbnail' src='" + picFile.result + "'" +
"title='" + file.name + "'/>";
output.insertBefore(div,null);
};
})(divn));
You can prefill argument (divn) , use closure to remember its status and return new function by using currying.
Hope this is helpful for you.