image preview before upload not working with + image+_row - javascript

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.

Related

Converting data:image base64 to blob in this code

I'd like to change the URLs from data:image base64 to blob. This is the original code that produces the base64 urls:
<script>
$(window).load(function(){
function readURL() {
var $input = $(this);
var $newinput = $(this).parent().parent().parent().find('.portimg ');
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
reset($newinput.next('.delbtn'), true);
$newinput.attr('src', e.target.result).show();
$newinput.after('<div class="delbtn delete_upload" title="Remove"><span class="bbb-icon bbb-i-remove2"></span></div>');
$("form").on('click', '.delbtn', function (e) {
reset($(this));
$("form").find('#rright-<?php echo $i;?>').hide();
});
}
reader.readAsDataURL(this.files[0]);
}
}
$(".file").change(readURL);
function reset(elm, prserveFileName) {
if (elm && elm.length > 0) {
var $input = elm;
$input.prev('.portimg').attr('src', '').hide();
if (!prserveFileName) {
$($input).parent().parent().parent().find('input.file ').val("");
//input.fileUpload and input#uploadre both need to empty values for particular div
}
elm.remove();
}
}
});
</script>
What I want is to call Object.createObjectURL(this.files[0]) to get the object URL, and use that as the src of your img; (just don't even bother with the FileReader).
Something like this?
function readURL() {
var file = this.files[0]
var reader = new FileReader();
var base64string = getBase64(file);
reader.onload = function () {
reset($newinput.next('.delbtn'), true);
$newinput.attr('src', e.target.result).show();
$newinput.after('<div class="delbtn delete_upload" title="Remove"><span class="bbb-icon bbb-i-remove2"></span></div>');
var blob = dataURItoBlob(base64string);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
I'm not sure if this will work and due to the vagaries of Stack Snippets, can't demonstrate its viability here on Stack Overflow, but theoretically, you should be able to use URL.createObjectURL to create the appropriate URL for your image, without going through the whole base 64 rigmarole.
var $newinput = $(this).parent().parent().parent().find('.portimg ');
if (this.files && this.files[0]) {
$newinput.attr('src', URL.createObjectURL(this.files[0]));
// if the above doesn't work, you could try to create a new Blob
var fileBlob = new Blob(this.files[0], { type: "image/png" })
// Substitute "image/png" with whatever image type it is
$newinput.attr('src', URL.createObjectURL(fileBlob));
That should render the appropriate URL for the image's source.
Note that it is best practice to revoke the object URL when you are done with it. I'm not sure that's necessary in this case, since presumably you want to show the image until the page is closed. However, if the user can upload a new image, do something like:
if ($newinput.attr('src').indexOf('blob') > -1) {
URL.revokeObjectURL($newinput.attr('src'));
}
Add that before setting the new source and you shouldn't need to worry about memory leaks (from this use of createObjectURL anyway...).
For more information on Blob URLs, see this answer by a now-anonymous user to What is a blob URL and why it is used?

Multiple Image Upload Preview with javascript

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>

Pre-visualising multiple pictures when selected

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);
});

Jquery image upload same image not uploading issue

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.

HTML5 FileReader API onload event not called

I am trying to implement the FileReader API to read an audio file, but the script never gets to that point from what it seems. My function is below and the trouble is at the reader.onload = handleReaderLoad; line.
function setupFS(file) {
console.log('setupFS function entered.');
var reader = new FileReader();
console.log(reader);
reader.onload = handleReaderLoad;
}
function handleReaderLoad(evt) {
console.log(reader);
var audioSrc = $('.file-playlist table tr:nth-child(n+1) td:first-child');
console.log(audioSrc);
console.log(reader.readAsDataURL(file));
audioSrc.attr('data-src', reader.readAsDataURL(file));
}
In the console, the reader shows up with the onload event as having a function handleReaderLoad(evt) { call, but the reader, audioSrc, and reader.readAsDataURL(file) variables are never logged in the console.
What am I missing?
I've figured out how the FileReader API wants the events to be set up. The main process of using a FileReader works by creating a FileReader, then declaring any/all of its events such as the onload or the onloadend events which are shown below. The process can also be condensed into one main function.
function readFile(file) {
var audioSrc;
audioSrc = $('.file-playlist table tr:nth-child(' + n + ') td:first-child');
var progress = $('.file-playlist table tr:nth-child(' + n + ') td:last-child progress');
n++;
progress.removeAttr('value');
progress.attr('data-mod', 'true');
var reader = new FileReader();
reader.onload = (function(file) {
return function(e) {
audioSrc.attr('data-src', e.target.result);
$('.file-playlist audio source').attr('data-src', e.target.result);
progress.attr('value', '100');
console.log('onload stage finished');
};
})(file);
reader.onloadend = (function() {
audioSrc.text(file.name);
});
reader.readAsDataURL(file);
}
The function works by creating a FileReader, then declaring its onload events by returning the function, and the reader is given content by reading in data at the end of the function, in this case by using the readAsDataURL() method.

Categories

Resources