javascript FileReader multiple not working - javascript

I'm using one input in html to select and upload image one by one or multiple.
I want to show preview before upload image and I'm using js FileReader. It's working for one image but not working for multiple images.
$('#fileToUpload').change(function(){
var file = this.files;
filepreview(file);
});
function filepreview(files)
{
var length = files.length;
for(var i=0 ; i<length ; i++)
{
var file = files[i];
var reader = new FileReader();
reader.addEventListener("load",function(e){
$('#pic'+i+'').attr('src' , ''+e.target.result+'');
});
reader.readAsDataURL(file);
}
}

Its basically that i is always length, as the events occur after the loop iterated:
reader.addEventListener("load",function(e){//async stuff
$('#pic'+i+'').attr('src' , ''+e.target.result+'');//i = length
});
So you may want to bind i:
reader.addEventListener("load",function(i,e){//take over the bound i
$('#pic'+i+'').attr('src' , ''+e.target.result+'');
}.bind(this,i));//the magic part

Related

Previewing Images in Order with JQuery

I'm trying to build a form in which it is possible to select images and then immediately preview all images, and flag certain images before the upload. The images are flagged using a checkbox which contain as value the name of the file, and the checkboxes are displayed on top of the images.
The images are visible, however the order in which they appear seems to be random and because of this the wrong checkbox is displayed over most of the images. Is there any way to control the order in which the images appear, or to put the correct checkbox with the correct image? This is the jQuery code that I am currently using.
$(function() {
// Multiple images preview in browser
var imagesPreview = function(input, placeToInsertImagePreview) {
if (input.files) {
var filesAmount = input.files.length;
counter=0;
for (i = 0; i < filesAmount; i++) {
var reader = new FileReader();
reader.onload = function(event) {
$($.parseHTML('<div class="imagewrapper" style="position:relative">'))
.append($($.parseHTML('<img class="parent-width">')).attr('src', event.target.result))
.append($($.parseHTML("<input class='imgcheckbox' name='featured[]' value='"+input.files[counter].name+"' type='checkbox'>")))
.appendTo(placeToInsertImagePreview);
counter++;
}
reader.readAsDataURL(input.files[i]);
}
}
};
$('#photoinput').on('change', function() {
imagesPreview(this, '.photoaddview');
});
});
In this fiddle: https://jsfiddle.net/4ad6zLfq/ : what I've done is used a LET variable, which is block scoped so your iteration variable won't ever get desynced from the image you're loading, and I've made your file loading 'reader' thing into a promise
function loadFile(file) {
return new Promise(function(resolve, reject) {
var reader = new FileReader();
reader.onload = function() {
resolve(event.target.result);
};
reader.readAsDataURL(file);
})
}
var imagesPreview = function(input, placeToInsertImagePreview) {
if (input.files) {
var filesAmount = input.files.length;
for (let i = 0; i < filesAmount; i++) {
loadFile(input.files[i])
.then(function(data) {
$($.parseHTML('<div class="imagewrapper" style="position:relative">'))
.append($($.parseHTML('<img class="parent-width">')).attr('src', data))
.append($($.parseHTML("<input class='imgcheckbox' name='featured[]' value='"+input.files[i].name+"' type='checkbox'>")))
.appendTo(placeToInsertImagePreview);
})
}
}
};
[edit]
for the record, this does NOT force the images to load in the correct order. It does, however, force the checkboxes next to the correct images, which was as you noticed a fault with the way it originally was. It's actually fairly easy to use async/await to take the example I created and ALSO make it load in order.

FileReader API to call images using same ID tag multiple times?

I've been trying to figure out how I can have the HTML5 FileReader API
display the same image more than once on duplicate id's.
An example of the implantation is here:
http://jsfiddle.net/2xES5/37/
A div gets created by click, and within each DIV created lies a call (id="list") to display images. Then when someone adds their images each newly created div contains the images.
But the problem is that the Filereader isn't recognizing multiple instances of the same div id.
It's only showing the images in one DIV where as I'd want the images repeated for each div.
Hopefully someone can send me towards the right path.
Thanks
 
Basic FileAPI: http://jsfiddle.net/2xES5/35/
if (window.File && window.FileReader && window.FileList && window.Blob) {
// Great success! All the File APIs are supported.
} else {
alert('Sorry The HTML5 FileReader API is not fully supported in this browser.');
}
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.setAttribute('class', 'spin');
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);
//</script>
The best solution:
Don't use duplicate IDs
Per the HTML spec, ID is meant to be unique in the document.
You'll notice that the API refers to:
document.getElementById -- note the singular element.
You'd be better off using either a CSS class name and selecting from it, or using a data- attribute, and selecting from that.
If you insist upon using a duplicate ID anyways:
document.querySelectorAll("#list"); -- This will deal with the invalid code of multiple IDs.
Update per comments
Both the document.getElementsByClassName and document.querySelectorAll return a node list -- an array-like structure that must be looped through.
From your usage, it seems like you come from a jQuery background, which hides all of that from by turning everything into an array and applying jQuery methods to that array. Straight JavaScript doesn't work like that.
When trying to figure out why things don't work in JavaScript, it is always a good idea to look at the value have. That will tell you a LOT.
var nodeList = document.querySelectorAll("#list");
console.log(nodeList);
console.log(nodeList.toString());
for (var i = 0; i < nodeList.length; i++) {
var node = listList[i];
var span = document.createElement("span");
span.appendChild(document.createTextNode("A span!");
node.insertBefore(span, null)
}
This did the Trick.
Thanks!
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<script>
window.preview = function (input) {
if (input.files && input.files[0]) {
$(input.files).each(function () {
var reader = new FileReader();
reader.readAsDataURL(this);
reader.onload = function (e) {
$(".list").append("<img class='thumb' src='" + e.target.result + "'>");
}
});
}
}
http://jsfiddle.net/qF7Ff/1/

how to get photo compleet url form form in array

I am trying to use jquery to take a picture from my comp via a form.
- So I want the entire URL out of the form in an array
It works + / - in Dreamweaver, but not in the explorer browsers not even chrome
The end goal is a calendar with picture / app for people with disabilities, but as long as I get to go through the phone gap
var foto= new Array();
var i=-1;
//foto=["toets.png"];
$('#fotouit').append("FOTO UIT");
$('#knop01').click(function(){
$('input:file[name=foto]').each(function(){
//alert($(this).val());
foto.push($(this).val());
foto.forEach( function(){
i++;
$('#fotouit').append(foto[i]);
$('#fotouit').append('<img src=" '+ foto[i] + ' " width="100" height="100" />');
});
});
})
I don't think it is possible to get the URL of the picture in you computer's local filesystem, but you can use Javascript's FileReader API to read the contents of the uploaded file (in your case, the picture). The read contents can be used in the src of the img element as you did in your example code.
This is an in depth explanation of what you're trying to accomplish: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
Example:
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /image.*/;
if (!file.type.match(imageType)) {
continue;
}
var img = document.createElement("img");
img.classList.add("obj");
img.file = file;
preview.appendChild(img); // Assuming that "preview" is a the div output where the content will be displayed.
var reader = new FileReader();
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
reader.readAsDataURL(file);
}
}
Note:
You can use the multiple attribute on a file input to allow selecting many files with one input
You can use the file inputs change event to immediately capture the files rather than providing a second button to click

Get file size in javascript for multiple files

I am using jQuery Form Plugin to upload my files via AJAX and I also want to check if size is more than 20mb on every file before I send them to server. I've discovered this HTML5 example, but I can't figure out how to put it together with my code here.
$(document).ready(function(){
$('.form-videos').ajaxForm({
success : function(data){
alert(data);
},
beforeSubmit : function(){
var fileInput = $('.form-videos :input[type=file]');
var totalFiles = $('.form-videos :input[type=file]').get(0).files.length;
for (i = 0; i < totalFiles; i++)
{
alert('what?'); // This works and prints out correctly for every file
// How do I get current file size?
}
}
});
});
You should be able to;
var files = $('.form-videos :input[type=file]').get(0).files;
for (i = 0; i < files.length; i++)
{
if (files[i].size > 20971520) ...
}
See an example here.
In your example, length is simply the number of selected files. You need to access the individual File objects and their size property.

Add or remove slides using jQuery FlexSlider

Is it possible to add or remove slides in runtime using FlexSlider?
The new version of FlexSlider 2 already supports this methods.
slider.addSlide(obj, pos) accepts two parameters, a string/jQuery object and an index.
slider.removeSlide(obj) accepts one parameter, either an object to be removed, or an index.
This is just what I saw after looking at this thread.
The slider and the carousel object can be instantiated and added to like this:
$('#slider').data('flexslider').addSlide("");
$('#carousel').data('flexslider').addSlide("");
The click on the carousel to scroll to the particular image doesn't work, but the scroll buttons on both work.
The actual implementation of FlexSlider doesn't support it.
If you modify the actual implementation to return the slider object, with this object you can stop the slider, remove the slide you want and then recreate the slider.
After trying lots of different ideas, I got this solution to add or remove a new image or video in Flexslider dynamically and its working fine.
JQuery code:
$("#add2").change(function(event)
{
var fuData = document.getElementById('add2');
var files = event.target.files;
for(var i = 0; i< files.length; i++)
{
var file = files[i];
var filename = file.name;
var Extension =
filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
if(Extension == 'png' || Extension == 'jpg' || Extension == 'jpeg' || Extension == 'svg'){
var reader = new FileReader();
reader.onload = function(e)
{
var img = document.createElement("IMG");
img.src = e.target.result;
div = "<li><img src="+img.src+" /></li>";
$('.flexslider').data('flexslider').addSlide($(div));
}
}
else if (Extension == 'mp4')
{
var reader = new FileReader();
reader.onload = function(event){
var video = document.createElement("video");
video.src = event.target.result;
div = " <li><video src="+video.src+" width='100%' height='500' controls></video></li>";
$('.flexslider').data('flexslider').addSlide($(div));
}
}
else
{
alert(filename+' '+'is not in supported format');
$("#add2").val('');
}
reader.readAsDataURL(file);
}
});
function remove()
{
var slider = $('.flexslider').data('flexslider');
slider.removeSlide(slider.currentSlide);
}
HTML code:
<input type="file" id= "add2" multiple>
<button id="remove" onclick="remove()" value="Remove">Remove</button>
as per the code, with browse file, you can select multiple images and videos to add in Flexslider and with remove button, you can remove a current slide.I also added some validation so only image or video will be add in a slider. It will give an alert if you select any other extension. I created this code as per my requirement, you can customize it accordingly to your requirements.

Categories

Resources