I'm using the following javascript inside my rails 5 app in order to preview the image before the form gets submitted.
The image form field has a setup for multiple files, but the javascript has a setup for only one. I can preview more then one image but eventually only one gets uploaded.
How can I make this javascript preview and upload multiple images?
<script>
function handleFileSelect(event)
{
console.log(event)
var input = this;
if (input.files && input.files[0])
{
var reader = new FileReader();
console.log(reader)
reader.onload = (function (e)
{
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="',e.target.result, '" title="', escape(e.name), '"/><span class="remove_img_preview"></span>'].join('');
document.getElementById('preview').insertBefore(span, null);
});
reader.readAsDataURL(input.files[0]);
}
}
//su kien thay doi hinh khac
$('#files').change(handleFileSelect);
//day la su kien click vao nut x để xóa ảnh
$('#preview').on('click', '.remove_img_preview',function ()
{
$(this).parent('span').remove();
$(this).val("");
});
</script>
Related
I'm trying to upload a file and convert that file to its data-uri counterpart without needing any sort of back-end, but I'm stuck at trying to figure out how to actually get the uploaded file.
document.getElementById("myInput").files[0]
allows me to access some information, but not the actual file. There's the file api, but I can't find much documentation about how to use it, just that it exists.
Is there any way to do this entirely in the browser?
Here's a code for multiple file input. You can do it for a single file by removing loop.
This will take the file as soon as you select file and displays inside the selected img tag
HTML Code
<div>
<img id="img-1" src="#" />
</div>
<div>
<img id="img-2" src="#"/>
</div>
Javascript Code
function readURL(input) {
if (input.files && input.files[0]) {
var countFiles = input.files.length;
for (var i = 0; i < countFiles; i++) {
// console.log(input.files);
if(i === 0) {
// console.log(input.files);
var reader = new FileReader();
reader.onload = function (e) {
// console.log(e);
$('#img-1')
.attr('src', e.target.result)
.width(135)
.height(135);
};
reader.readAsDataURL(input.files[i]);
}else if(i === 1) {
var reader = new FileReader();
reader.onload = function (e) {
// console.log(e);
$('#img-2')
.attr('src', e.target.result)
.width(135)
.height(135);
};
reader.readAsDataURL(input.files[i]);
}
}
}
}
I have this code to pre-visualise the pic we selected in the form.
It works fine when there is only one picture but I don't know what do modify if I want multiple files to be selected and previsualised for multiple pictures.
I tried to copy paste this one time per pic but seems not to work like this (I am not so good in js).
How should I modify it to make it work for image 1, image 2, image3, etc...
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#image1').css('backgroundImage', "url(" + e.target.result + ")" );
}
reader.readAsDataURL(input.files[0]);
}
}
$("#profile-img1").change(function(){
readURL(this);
});
am trying to upload multiple images using jquery. but same images are not uploading. how to solve this issue please check my fiddle
$images = $('.imageOutput')
$(".imageUpload").change(function(event){
readURL(this);
});
function readURL(input) {
if (input.files && input.files[0]) {
$.each(input.files, function() {
var reader = new FileReader();
reader.onload = function (e) {
$images.append('<img src="'+ e.target.result+'" />')
}
reader.readAsDataURL(this);
});
}
}
click here for jsfiddle
Just set the value of your file input to null once you are done with fetching the URL like below:
http://jsfiddle.net/q9Lx1Lss/23/
$images = $('.imageOutput')
$(".imageUpload").change(function(event){
readURL(this);
this.value = null; //setting the value to null
});
function readURL(input) {
if (input.files && input.files[0]) {
$.each(input.files, function() {
var reader = new FileReader();
reader.onload = function (e) {
$images.append('<img src="'+ e.target.result+'" />')
}
reader.readAsDataURL(this);
});
}
}
You were getting issue because on second time after selecting the same image, change event was not getting fired because of same file selection. Now after adding this.value = null; code we are clearing the previous file selection and hence every time change event will get executed irrespective of whether you select same file or different one.
When I select a image it should preview a image. But when I add my var image_row to onchnage it does not work.
I am trying to make it work with my onclick function function add_popup_image()
Codepen Example Here
Working single id
$("#fileupload_extra_image").change(function(){
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#input-popup-image').attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
Not Working
$('#fileupload_extra_image' + image_row).change(function(){
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#input-popup-image' + image_row).attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
Question: How Can I Make The + image_row work with my image preview script
The below was your problem:
image_row used to return always +1 i.e. if there existed
input-popup-image1 then it retrieved input-popup-image2. For time
being I just negated the value before searching for the id. You just
need to take care of the increment of image_row or the below code would just work fine.
Pen Here
$('#fileupload_extra_image' + image_row).on('change',function(){
if (this.files && this.files[0]) {
var reader = new FileReader();
var imgrw=image_row-1;
reader.onload = function (e) {
$('#input-popup-image' + imgrw).attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
UPDATE
To the problem you mentioned in your comments I would suggest to choose the below approach:
Updated Pen
Add a classname for the dynamically added controls image_preview and browse and then obtain its preview content which will be inside its root parent .row. So, this will avoid obtaining with id and keeping track of image_row value:
$(document).on('change','.file',function(){
if (this.files && this.files[0]) {
var imgpr=$(this).parents('div.row').find('.imgpr')
var reader = new FileReader();
reader.onload = function (e) {
$(imgpr).attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
$('#fileupload_extra_image' + image_row).change(function(){
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#input-popup-image' + image_row).attr('src', e.target.result);
image_row++;
}
reader.readAsDataURL(this.files[0]);
}
});
The problem is that you update image_row before the callback function for reader actually runs. What's happening is that you add an event listening on fileupload_extra_image + image_row for a change event which is fine. Then, it looks like you do a check for files and you do another event listener for reader on load. Note that this doesn't actually run this line of code yet:
$('#input-popup-image' + image_row).attr('src', e.target.result);
It's just simply saying that when reader is done loading, then run it.
Your function then continues and updates image_row which cause the previous line to use a value of 2 instead.
What my fix does is updates image_row only after a successful load is done.
I have an image upload preview. And, when user click in .thumb, I want to clone the input text name and show this. But clone()isn't working.
thanks
JSFIDDLE
HTML
<input type="file" id="files" name="files[]" multiple /><br />
<output id="list"></output><br />
<p>Name:<input type="text" class="name"/><p>
<br />
JS
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
$('.thumb').click(function() {
$('p').clone();
});
I think this will do what you want to do. I don't know what you were doing with the .click, but I moved the HTML to your loop that generates the thumbs.
Fiddle: http://jsfiddle.net/howderek/emTAX/17/
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
$('.name').clone().appendTo(".name");
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function (theFile) {
return function (e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ('<img class="thumb" src="' + e.target.result + '" title="' + escape(theFile.name) + '"/><p>Name:<input type="text" class="name" /></p>');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
what about this..
im still confused about what you want to do.. but the click event wasnt working due to the image not being there when the dom was ready, after the fact
http://jsfiddle.net/emTAX/25/
$('body').on("click",".thumb",function() {
var myclone = $("p input").clone();
$('p:first').append(myclone);
});
append() is faster than appendTo()
basically using on() will keep the event listening for the .thumb and then attach the event on it
http://api.jquery.com/on/