am trying to show the image name also in multiple image upload.in case of single selection its working but in case of multiple selection image name Repeats. please check my fiddle. am also trying to show the image path
You just need to change:
Working Fiddle: https://jsfiddle.net/1kojL0pk/
var f = $('.trnsupload').prop("files")[0]['name'];
To
var f = $('.trnsupload').prop("files")[i]['name'];
// Full Code:
window.Transfer = function (input) {
if (input.files && input.files[0]) {
$(input.files).each(function (i) { // add index over here
var f = $('.trnsupload').prop("files")[i]['name']; // access file using i-th index
var reader = new FileReader();
reader.readAsDataURL(this);
reader.onload = function (e) {
$("#Viewer").append("<div class='imageContainer'><img onclick='changeIt(this)' class='thumb img-thumbnail' src='" + e.target.result + "'> <span class='MultiFile-title'>" + f + "</span> <span class='loader'><img src='../../Images/ajax-loader.gif' /></span> <span class='closeCover glyphicon glyphicon-remove'></span></div>");
}
});
}
}
Related
I am selecting multiple images using html tag 'input file multiple html' as below.
#Html.TextBoxFor(model => model.files, "",
new {#id = "filesToUploadID", #type = "file", #multiple = "multiple" })
<div class="col-md-10" id="selectedFiles"></div>
Then in javascript, I attached 'onchange' event listner to the above tag. When I select multiple images, I get all the attached images to the tag using jquery. But I need image file names as well. While getting image file names, I get only one file name poplulated in my html along with image using jquery.
jquery/ javascript is below
document.addEventListener("DOMContentLoaded", init, false);
function init() {
document.querySelector('#filesToUploadID').addEventListener('change', handleFileSelect, false);
selDiv = document.querySelector("#selectedFiles");
}
function handleFileSelect(e) {
debugger;
NameArray = [];
if (!e.target.files) return;
selDiv.innerHTML = "";
var files = e.target.files;
for (var i = 0; i < files.length; i++) {
var f = files[i];
NameArray.push(f.name);
var reader = new FileReader();
reader.onload = function (e) {
var html = "<img src='" + e.target.result + "' />";// + "<div>" + + "</div>";//+ "<br clear=\"left\"/>";
$(selDiv).append($(html));
//selDiv.innerHTML += html;
}
reader.readAsDataURL(f);
}
}
I tool help from this link and implemented both ways but could not succeed.
All images names are relevant to the images. What I am getting is like this
It's source code is
I have to assign id's based on image names that's why it is important to get relevant image names. Any lead to the topic will be high appreciated.
Thank you.
var f = files[i];
var fileName = e.target.f.name
This question already has an answer here:
How to set file input value when dropping file on page? [duplicate]
(1 answer)
Closed 4 years ago.
I have a small HTML5 form where the user drops an image file, sees the preview, gets to know the dimensions of the image, fills an input element, and hits the button "Send" to dispatch it all (image and input text) through a POST request.
Problem is, the image data is not being sent together with the input data, even if the div and img elements have a name tag assigned to them. How can I accomplish that using the usual POST process?
Here is my code.
function removeDragData(e) {
if (e.dataTransfer.items) { // Use DataTransferItemList interface to remove the drag data
e.dataTransfer.items.clear();
} else { // Use DataTransfer interface to remove the drag data
e.dataTransfer.clearData();
}
}
function formatBytes(a,b) {
if (0 == a)
return '0 Bytes';
var c = 1024,
d = b || 2,
e = ['Bytes','KB','MB','GB','TB','PB','EB','ZB','YB'],
f = Math.floor(Math.log(a)/Math.log(c));
return parseFloat((a/Math.pow(c,f)).toFixed(d))+' '+e[f];
}
function getDim(img,tam) {
var infoW = img.naturalWidth;
var infoH = img.naturalHeight;
var info = document.getElementById('addDadoInfo');
info.innerHTML = 'Tamanho: ' + infoW + ' x ' + infoH + ' pixels (' + formatBytes(tam) + ')';
}
function drop(e,who) {
e.preventDefault(); // Prevent default behavior (Prevent file from being opened)
var i;
if (e.dataTransfer.items) { // Use DataTransferItemList interface to access the file(s)
for (i=0; i<e.dataTransfer.items.length; i++) {
if (e.dataTransfer.items[i].kind === 'file') { // If dropped items aren't files, reject them
var file = e.dataTransfer.items[i].getAsFile();
if (file.type.indexOf('image/') == 0 && file.size <= 2*1024*1024) {
// Process only the first image up to 2 MB
var img = document.createElement('img');
var tam = file.size;
img.file = file;
img.name = 'imgDImg';
img.style.maxWidth = '400px';
img.style.maxHeight = '300px';
while (who.firstChild) {
who.removeChild(who.firstChild); // removes the <p> element
}
who.appendChild(img);
var reader = new FileReader();
reader.onload = (function(aImg) {
return function(ev) {
aImg.src = ev.target.result;
setTimeout(getDim,500,aImg,tam);
};
})(img);
reader.readAsDataURL(file);
break;
//console.log('.A. file[' + i + '] = ' + file.name + '|' + file.type + '|' + file.size);
}
}
}
} else { // Use DataTransfer interface to access the file(s)
for (i=0; i<e.dataTransfer.files.length; i++) {
var file = e.dataTransfer.files[i];
console.log('.B. file[' + i + '] = ' + file.name + '|' + file.type + '|' + file.size);
}
}
removeDragData(e); // Pass event to removeDragData for cleanup
}
function dragOver(e) {
e.preventDefault(); // Prevent default behavior (Prevent file from being opened)
}
.addDado {
background-color:#DDD;
width:400px;
height:300px;
text-align:center;
}
<form id='frmAddDado' autocomplete='on' method='post' action='index.php'>
<div id='addDado1' name='addDado1' class='addDado' ondrop='drop(event,this)' ondragover='dragOver(event)'>
<p>Drop image here.</p>
</div>
<div id='addDadoInfo'>(No data selected.)</div>
<br>
<label for='txaDRef'>Reference</label><br>
<textarea id='txaDRef' name='txaDRef' cols=80 rows=5></textarea><br>
<br>
<input id='btnAddDado' type='submit' value='Add' disabled />
</form>
Well, this answer helped me to get it partially done, converting the image into base64 and attaching this to a hidden input. However, it's only 100% ok for PNG images. If the user tries to upload a JPG, there's no way it seems I can save the file as-is, i.e. without losing quality or increasing the file size.
So, I'm still looking for a better way to have both: thumbnail, dimensions and file size displayed and perfect file transfer.
EDIT
Digging more, I've found this answer, which does exactly what I needed!
A few modifications to the code above:
// in <form id='frmAddDado'>
<input id='fileIMG' name='fileIMG' type='file' style='display:none' />
// in function drop(e,who)
document.getElementById('fileIMG').files = e.dataTransfer.files;
Hi all i have code for multiple upload image, but i want only one image per upload. so I create the input file every time I clicked the upload button with the dynamic id. however I have problems checking whether the user chooses the file to upload or press the cancel button. because if the user pressed the cancel button I want to delete the input file I have created. for full sourcenya as below:
$(document).ready(function () {
$("#btnimg").click(function () {
//check input file id number
var counter = $("input[id^='upload']").length;
//add input file every btnimg clicked
var html = "<input type='file' id='upload_" + counter + "' style='display:none;'/>";
$("#result").append(html);
//trigger to dialog open file
var upload = $('#upload_' + counter);
upload.trigger('click');
upload.on('change', function () {
console.log('change fire...');
var inputFiles = this.files;
var inputFile = inputFiles[0];
var reader = new FileReader();
reader.onload = function (evt) {
var imghtml = "<img id='img_upload_" + counter + "' src='" + evt.target.result + "' width='50px;' height='50px;'/>";
$('#previewimage').append(imghtml);
};
reader.onerror = function (event) {
alert("something: " + event.target.error.code);
};
reader.readAsDataURL(inputFile);
});
//if file not selected or user press button cancel on open dialog
//upload.remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="result"></div>
<button id="btnimg">upload image</button>
<div id="previewimage">
</div>
</body>
thank you in advance,
You can check the .length of <input type="file"> element .files property to determine if a file is selected by user
That all sounds like an xy-problem to me.
I have not (yet) got a response from you about the why you want to do it, so I will base my answer on two probable situations:
If you want to keep track of the selected Files, in order to be able to do anything with them later (e.g send them through AJAX), then use a single <input>.
At every change event, you will store the new File in an Array, from where you will also be able to do something with later on:
(function() {
// this Array will hold our files, should be accessible to the final function 'doSomething'
var savedFiles = [];
var counter = 0;
var upload = $('#upload');
upload.on('change', onuploadchange);
$("#btnimg").click(function routeClick() {
upload.trigger('click');
});
$('#endbtn').click(function doSomething() {
console.log(savedFiles);
});
function onuploadchange() {
var inputFiles = this.files;
var inputFile = inputFiles[0];
if (!inputFile) { return; } // no File ? return
savedFiles.push(inputFile); // save this File
// don't use a FileReader here, useless and counter-productive
var url = URL.createObjectURL(inputFile);
var imghtml = "<img id='img_upload_" + counter + "' src='" + url + "' width='50px;' height='50px;'/>";
$('#previewimage').append(imghtml);
$('#endbtn').removeAttr('disabled');
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result">
<!-- A single input to save them all-->
<input type='file' id='upload' style='display:none;' />
</div>
<button id="btnimg">upload image</button>
<div id="previewimage">
</div>
<button id="endbtn" disabled>do something with saved files</button>
If, for an obscure reason, you absolutely need to keep all the filled <input> elements in your document, then create a new one only if the last one is itself filled.
$(document).ready(function() {
$("#btnimg").click(function() {
// grab previous ones
var inputs = $("input[id^='upload']");
// get the last one we created
var last = inputs.last();
var counter = inputs.length;
console.log(counter);
var upload;
// if there is no input at all, or if the last one is already filled with a File
if (!last.length || last[0].files.length) {
console.log('create new input');
upload = makeNewInput();
} else {
// use the last one
upload = last;
}
//trigger to dialog open file
upload.trigger('click');
function makeNewInput(counter) {
var html = "<input type='file' id='upload_" + counter + "' style='display:none;'/>";
var el = $(html);
el.on('change', onuploadchange);
$('#result').append(el);
return el;
}
function onuploadchange() {
var inputFiles = this.files;
var inputFile = inputFiles[0];
var url = URL.createObjectURL(inputFile);
var imghtml = "<img id='img_upload_" + counter + "' src='" + url + "' width='50px;' height='50px;'/>";
$('#previewimage').append(imghtml);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
<button id="btnimg">upload image</button>
<div id="previewimage">
</div>
I have a multi-upload for image files, and the problem that I used to face was that the images are appearing in a different sequence as the user's input. For example, user selects Img1, Img2, Img3, Img4. The sequence that it appears might be Img2, Img4, Img3, Img1.
This causes a problem as I have to link them to a text field (image description), and each text field has to match the right image. I did some digging and found out that i can use this code here to make sure that it is being uploaded in the same sequence:
html
<input id="uploadfiles" multiple="multiple" name="photos" type="file">
javascript
$("#uploadfiles").change(function(){
imgpreview(document.getElementById('uploadfiles').files);
});
function imgpreview(files) {
var count = 0;
for (var i = 0, f; f = files[i]; i++) {
(function () {
var div = $("<div></div>");
var reader = new FileReader();
$(".display").append(div);
reader.onload = function(e) {
div.append("<img id='photocount" + count + "' src='" + e.target.result + "' style='height:40px;width:auto;'></img>");
count++;
};
reader.readAsDataURL(f);
}());
}
}
It is also available in fiddle here: https://jsfiddle.net/L3d1L9t3/1/
This javascript code here ensures that the images are appearing in sequence. However, the id for the images are still not in order. For example, if 4 images are uploaded, the ids should be photocount0, photocount1, photocount2, photocount3 respectively. But this is not the case when i inspect element on each of the images.
How do i ensure that the "count" is in sequence as well? This is important since i need to match the count to the text field (image description) as well ["image 1" is paired with "image description 1", "image 2" is paired with "image description 2" and so on]
Use URL.createObjectURL(file) instead it's both faster and easier since it's sync - you don't have to encode/decode back and fort to/from base64 then
$("#uploadfiles").change(function() {
// imgpreview(document.getElementById('uploadfiles').files); <-- not needed
imgpreview(this.files)
})
function imgpreview(files) {
var url, div, len = files.length
var $display = $(".display")
for (var i = 0; i < len; i++) {
url = URL.createObjectURL(files[i])
div = $('<div>')
$display.append(div)
div.append("<img id='photocount" + i + "' src=" + url + " style='height:40px;width:auto'>")
}
}
I'm working on a simple script for my site to upload images. I have a multiple file input <input type = 'file' name = 'files[]' id = 'hiddenFile' multiple> that is being triggered by a div click. When I queue the files, I want to be able to delete one. I know I can loop through the $('#hiddenFile').val() and splice to get the name out but I'm having an issue with figuring out the file name. When I assign the file to a new img container, how do I get the name? I've tried console.log(f.name) and a few variations but it returns an undefined error. Here are my scripts. I think I'm pretty close but this is something I'm learning as I go. Thanks!
function readURL(input) {
var files = $('#hiddenFile')[0].files; //where files would be the id of your multi file input
//or use document.getElementById('files').files;
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = function (e) {
console.log(f.name); //how can I get the
//file name here to add it to the image as an attribute?
$("<img src = '"+e.target.result+"' class = 'addedImg'>").appendTo("#imgBox");
};
reader.readAsDataURL(f);
}
}
$(document).ready(function(){
$(document).on('click', '#addBtn', function(e){
e.preventDefault();
$('#hiddenFile').click();
});
});
Try using change event , defining f within an IIFE , setting title attribute value to f.name
$(document).ready(function() {
$(document).on('click', '#addBtn', function(e) {
e.preventDefault();
$('#hiddenFile').click();
});
$("#hiddenFile").change(function(event) {
var files = this.files;
var i = 0,
len = files.length;
(function readFile(n) {
var reader = new FileReader();
var f = files[n];
reader.onload = function(e) {
console.log(f.name);
$("<img src=" + e.target.result + " class=addedImg title=" + f.name + ">")
.appendTo("#imgBox");
// if `n` is less than `len` ,
// call `readFile` with incremented `n` as parameter
if (n < len -1) readFile(++n)
};
reader.readAsDataURL(f); // `f` : current `File` object
}(i)); // `i` : `n` within immediately invoked function expression
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="addBtn">click</div>
<input type="file" style="display:none" id="hiddenFile" multiple />
<div id="imgBox"></div>
The FileReader object itself does not have access to the file name. You get the file name while you're iterating over the files list as you are doing in your for loop.
var reader = new FileReader();
reader.onload = function (e) {
//update image src or something
};
for (var i = 0, f; f = files[i]; i++) {
reader.readAsDataURL(f); //updates image src or something
//additional method to do something with file name goes here
}
And if you really want to have one method that does those two things in the for loop, then you can wrap it all up in a closure like #ebidel does in his answer here - Get filename after filereader asynchronously loaded a file#answer-12547471.