how to loop this function? - javascript

Thanks to some help on here I have a way of previewing images selected for and upload using:
<input type='file' name="files[]" onchange="readURL(this);" multiple />
<div id="previews"></div>
<script>
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
var container = $('#previews');
var image = $('<img>').attr('src', e.target.result).width(150);
image.appendTo(container);
};
reader.readAsDataURL(input.files[0]);
}
}
</script>
I was wondering how to loop this function for each file selected on the input? I just don't see where to use something like .each()
edit:
am trying this.. but its wrong somewhere, as it displays 2 previews but both of the same image?
function readURL(input) {
$.each(input.files,function(i) {
var reader = new FileReader();
reader.onload = function (e) {
var container = $('#previews');
var image = $('<img>').attr('src', e.target.result).width(150);
image.appendTo(container);
};
reader.readAsDataURL(input.files[0]);
});
}

input.files is a FileList, which acts like an array.
You can use jQuery.each on it like any other array.

You just need to loop over the last line, where the file is selected.
function readURL(input) {
var reader = new FileReader();
reader.onload = function (e) {
var container = $('#previews');
var image = $('<img>').attr('src', e.target.result).width(150);
image.appendTo(container);
};
$.each(input.files,function(i) {
reader.readAsDataURL(input.files[i]);
});
}

Related

Can not preview multiple uploading files in form

In a multipart form, I can preview a single uploading image using:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = `${e.target.result}`;
image.className = "img-thumbnail"
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$('#images-to-upload').append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#imgInput").change(function () {
readURL(this);
});
But I'd like to preview ALL uploading images, so I made this adjustment to the code above by adding a for loop:
function readURL(input) {
if (input.files && input.files[0]) {
let files = input.files;
for (var i = 0; i < input.files.length; i++) {
var reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = `${e.target.result[i]}`;
image.className = "img-thumbnail"
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$('#images-to-upload').append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
}
};
reader.readAsDataURL(input.files[i]); // error here
}
}
But now I get this error:
143 Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'
How can I fix this?
It's because the reader.readAsDataURL(input.files[i]); is outside the loop. But this is not how you do this. The FileReader can process only one file at the time. This means you have to create an instance of the FileReader for each image in the input.
I would suggest to split it into 2 functions for readability.
function previewImage(file) {
const reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = e.target.result;
image.className = "img-thumbnail";
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$("#images-to-upload").append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
};
reader.readAsDataURL(file);
}
function readURL(input) {
if (input.files.length) {
Array.from(input.files).forEach((file) => previewImage(file));
}
}
I made some changes:
if (input.files.length) { - the file input always have files FileList object so no need to check if it exists, and you just check if it has a length, meaning at least one file is present
Array.from(input.files) - transforms FileList into a regular array fo you can use array functions, like forEach
The rest is pretty much the same. In image.src = e.target.result;, there's no need to make it string as it is already a string. Also the result set on the FileReader class cannot be array.

When I insert a file in an input file it shows preview, but how to delete a selected file?

I got this javascript to show image preview when user select the file, it is working.
Case:
- If user select wrong image and delete it then preview do not refresh to 'empty'.
I have no idea how can I do this, already lookd around google and stackoverflow and nothing. Can someone give me a light please?
<img id="image1" width="300px" height="300px"/>
<img id="image2" width="300px" height="300px"/>
<img id="image3" width="300px" height="300px"/>
<img id="image4" width="300px" height="300px"/>
<script>
document.getElementById("productimage1").onchange = function () {
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById("image1").src = e.target.result;
};
reader.readAsDataURL(this.files[0]);
};
document.getElementById("productimage2").onchange = function () {
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById("image2").src = e.target.result;
};
reader.readAsDataURL(this.files[0]);
};
document.getElementById("productimage3").onchange = function () {
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById("image3").src = e.target.result;
};
reader.readAsDataURL(this.files[0]);
};
document.getElementById("productimage4").onchange = function () {
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById("image4").src = e.target.result;
};
reader.readAsDataURL(this.files[0]);
};
</script>
If I get what you want correctly...
You want the image preview to be cleared when user tries to select a new image using the "open file" window. No delete button.
Here is what you should do then:
// A delete function
$("[id^='product']").on("click",function(){
// This clears the input value.
$(this).val("");
// This resets the preview.
var imageID = $(this).attr("id").substr(7);
$("#"+imageID).attr("src","https://placehold.it/300x300");
});
See in CodePen
---EDIT
Here is the full code optimized.
// A delete function
$("[id^='product']").on("click",function(){
// This clears the input value.
$(this).val("");
// This resets the preview.
var imageID = $(this).attr("id").substr(7);
$("#"+imageID).attr("src","https://placehold.it/300x300");
});
// The preview function
$("[id^='product']").on("change",function(){
var imageID = $(this).attr("id").substr(7);
// Displays a preview im the right div
var reader = new FileReader();
reader.onload = function (e) {
$("#"+imageID).attr("src",e.target.result);
};
reader.readAsDataURL(this.files[0]);
});
See in CodePen - version #2

Display Image Preview instead of text [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
We are trying to upload an image to our site.
We click on "Upload Image" button.
Then it displays pop up box.
Then we click on Upload New image button
After that, we will select image from computer & displaying message Image uploaded
Instead of message "Image uploaded", i want to display preview of Uploaded image as like this Jsfiddle
code to display message "Image uploaded"
<input type="file" id="add_image_{{rand}}" class="newcustomimage" name="new_image" value=""/>
js
jQuery(document).ready(function () {
jQuery('body').delegate('.newcustomimage', 'change', function () {
if(jQuery(this).val()) {
jQuery(this).parent().parent().append('<div id="add_image_2508269_success" class="success-message validation-advice"> Image Uploaded.</div>');
}
});
});
I did below changes for above code to display "Image Preview" instead of message. Now Image preview is not displaying after we upload image. Instead its displaying like below image before we uploading an image in site.
<input type="file" id="add_image_{{rand}}" class="newcustomimage" name="new_image" value=""/>
<img id="blah" src="http://example.com/media/custom_product_preview/quote" />
Js
jQuery(document).ready(function () {
jQuery('body').delegate('.newcustomimage', 'change', function () {
if (jQuery(this).val()) {
jQuery(this).parent().parent().append('<div id="add_image_2508269_success" class="success-message validation-advice"> Image Uploded.</div>');
}
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
To do that please follow below
add this in your html
<input type="file" id="add_image_{{rand}}" data-rand={{rand}} class="newcustomimage" name="new_image" onchange="readURL(this);" value="" />
<img id="previewImg" src="#" style="display: none;height: 200px; width: 200px;" >
The java script for the same will be.
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
jQuery('#previewImg').attr('src', e.target.result);
jQuery('#previewImg').show();
}
reader.readAsDataURL(input.files[0]);
}
}
This will work in your case please have a try.
This seems to be working fine. Just need to configure the dimensions of the image.
Apply the following css:
.tool-body.selected {
text-align: center;
}
#previewImg {
height: 75px;
display: inline-block;
}
Also correct the spelling of uploaded.
EDIT
The following code works perfectly for the OP and meets his requirement:
jQuery(document).ready(function() {
jQuery('body').on('.newcustomimage', 'change', function() {
if (jQuery(this).val()) {
console.log(jQuery(this).val());
if (jQuery(this).val()) {
var reader = new FileReader();
}
jQuery(this).parent().parent().append('<div id="add_image_2508269_success" class="success-message validation-advice"> Image Uploaded.</div>');
}
});
jQuery(".aitcg-button").click(function() {
jQuery('#previewImg').hide();
});
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
jQuery('#previewImg').attr('src', e.target.result);
jQuery('#previewImg').show();
};
reader.readAsDataURL(input.files[0]);
}
}
The screengrab to the working site can be found here.
You can try like this
HTML
<input type="file" id="add_image_{{rand}}" class="newcustomimage" name="new_image" value=""/>
<div id="imgcontaner"></div>
JS
$(".newcustomimage").change(function() {
var input = this;
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$("#imgcontaner").empty();
$('<img/>').appendTo("#imgcontaner")
.attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
});
You have not called function on file select. You need to change it like this:
jQuery(document).ready(function (){
jQuery('body').delegate('.newcustomimage', 'change', function (){
if (jQuery(this).val())
{
readURL(jQuery(this));
}
});
});
keep there readurl function outside jQuery(document).ready
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
jQuery('#blah').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}

two js scripts blocking each other

I have a function that previews an image that is about to be uploaded:
<script>
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
var if_alternative = true;
$('#preview_image').attr('src', e.target.result);
//hide product_images and fileSelector
}
reader.readAsDataURL(input.files[0]);
}
}
$("#product_images").change(function(){
readURL(this);
});
</script>
Since users are able to upload more than one image, I would like the second image to be previewed as well. This is the function that is supposed to preview the second image:
<script>
function readURL(input) {
if (input.files && input.files[0]) {
var reader2 = new FileReader();
reader2.onload = function (e) {
var if_alternative2 = true;
$('#preview_image2').attr('src', e.target.result);
}
reader2.readAsDataURL(input.files[0]);
}
}
$("#product_images2").change(function(){
readURL(this);
});
</script>
Now, the problem is that, when both scripts are active, they both preview the image in the second image container (#preview_image2), instead of previewing the first one in the first container, and the second one in the second. Can anybody tell me why? Thanks!
The idea of using a function is to avoid duplicating code, so...
<script>
function readURL(input)
{
var reader;
if (input.files && input.files[0])
{
reader = new FileReader();
reader.onload = function (e)
{
var id = $(input).attr("id"),
new_id = id.substr(0, id.length - 1); // remove 's'
$("#" + new_id).attr('src', e.target.result);
//hide product_images and fileSelector
};
reader.readAsDataURL(input.files[0]);
}
}
$("#product_images, #product_images2").change(function()
{
readURL(this);
});
</script>
Notice that variables are ALL defined at the top of a function. It is safer to define them there so you can see all the variables that you are using and avoid mixing them (not like in C/C++ where braces define a scope.)
Also, a variable defined in a parent function is available as is to the sub-functions. Quite practical.

How to remove image preview when cleared?

I have a program where a selected image is previewed. Here is the code I use.
Javascript
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#preview').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#uploadphoto").change(function(){
readURL(this);
$('#preview').show();
});
But when I remove it with this:
$('#preview').on("click", function () {
$('#uploadphoto').replaceWith( selected_photo = $('#uploadphoto').clone( true ) );
$('#preview').attr('src', '');
});
The photo still is displayed. When I submit the page the photo is not submitted, which I wanted, but how do I get rid of the preview image? $('#preview').attr('src', ''); didn't seem to work...?
You'd use removeProp() for that, as just changing the attribute isn't enough:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#preview').attr('src', e.target.result).show();
}
reader.readAsDataURL(input.files[0]);
}
}
$("#uploadphoto").change(function () {
readURL(this);
$('#preview').show();
});
$('#preview').on("click", function () {
$('#uploadphoto').replaceWith(selected_photo = $('#uploadphoto').clone(true));
$('#preview').removeProp('src').hide();
});
FIDDLE
You should also hide and show the image, to make sure the "empty image" icon doesn't show, or you could just remove the element all together and insert a new one each time.
EDIT:
To fade the image out, do:
$('#preview').on("click", function () {
$('#preview').fadeOut(1000, function() {
$(this).removeProp('src');
$('#uploadphoto').replaceWith(selected_photo = $('#uploadphoto').clone(true));
});
});

Categories

Resources