I see this particular code everywhere on Stackoverflow and many suggested that it needs to be converted from FileReader() to URL.createObjectURL Doing so will make it faster and the links will be shorter. But I have yet to find a working solution. (It's an image preview script that shows image thumbs on upload).
Can somebody help me convert it?
<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));
});
}
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>
If I understand you mean correctly, you may want to use URL.createObjectURL function like this:
// your url will look like this
// blob:http://example.com/a298356a-ad76-4353-a35f-b6e22a0e792f
var url = URL.createObjectURL(this.files[0]);
Full code:
function readURL() {
var $input = $(this);
var $newinput = $(this).parent().parent().parent().find('.portimg ');
if (this.files && this.files[0]) {
var url = URL.createObjectURL(this.files[0]);
reset($newinput.next('.delbtn'), true);
$newinput.attr('src', url).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));
});
}
}
Related
I would like to know how I can get the value from a filereader() function.
Here is the code :
$(document).ready(function(){
$('#file_input').on('change', function(e){
readFile(this.files[0], function(e) {
var txt = e.target.result
var lines = txt.split("\n");
var url_check = null;
$.each(lines, function(n, data) {
if (n == 0 && data != "") {
url_check = data
}
});
$('#output_field').text(url_check);
});
console.log(url_check)
});
});
function readFile(file, onLoadCallback){
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsText(file);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="file_input" type="file">
<div id="output_field"></div>
And I have this error :
Uncaught ReferenceError: url_check is not defined
My goal is to return the variable url_check to be accessible outside the readFile function
I also tried declaring url_check outside the readFile function like :
$(document).ready(function(){
$('#file_input').on('change', function(e){
var url_check = null;
readFile(this.files[0], function(e) {
var txt = e.target.result
var lines = txt.split("\n");
$.each(lines, function(n, data) {
if (n == 0 && data != "") {
url_check = data
}
});
$('#output_field').text(url_check);
});
console.log(url_check)
});
});
function readFile(file, onLoadCallback){
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsText(file);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="file_input" type="file">
<div id="output_field"></div>
Since you are declaring the url_check variable inside $(document).ready(function() ..., it means it is going to be accessible only there. A solution would be to declare the parameter globally, so that any changes from the function would be still visible. If you want to do something with the variable after it is assigned, you'd have to call the function there, immediately. Calling it before might result in null results, since the file wasn't processed yet. See the jsfiddle below. I tested it any it does what you want.
$(document).ready(function() {
$('#file_input').on('change', function(e) {
readFile(this.files[0], function(e) {
var txt = e.target.result
var lines = txt.split("\n");
if (lines && lines.length > 0)
url_check = lines[0];
$('#output_field').text(url_check);
console.log(url_check);
callbackPrint();
});
});
});
var url_check = null;
function readFile(file, onLoadCallback) {
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsText(file);
}
function callbackPrint() {
console.log("From testPrint: " + url_check);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="file_input" type="file">
<div id="output_field"></div>
Since the function is run asynchronously you should consider using a promise or a callback function to resolve/return the url_check in order to access it outside of the readFile function.
If you just want to log the value of url_check out console.log(url_check) must be placed inside the readFile
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.
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));
});
});
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]);
});
}
I'm trying to get this piece of code work in Chrome (latest build 10.0.648.205) and it works as expected in Firefox. Here, the e.target.result of the showImage function is empty. Can anyone tell me what Am I doing wrong?
$(function () {
var dropbox = document.getElementById("dropimage");
dropbox.addEventListener("dragenter", function (e) {
this.className = "over";
e.preventDefault();
e.stopPropagation();
}, false);
dropbox.addEventListener("dragover", function (e) {
e.preventDefault();
e.stopPropagation();
}, false);
dropbox.addEventListener("dragleave", function (e) {
var target = e.target;
if (e && e === dropbox) {
this.className = "";
}
e.preventDefault();
e.stopPropagation();
}, false);
dropbox.addEventListener("drop", function (e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files;
var count = files.length;
if (count > 0) {
handleFiles(files)
}
}, false);
function handleFiles(files) {
$("#droplabel").html("Processing...");
file = files[0];
var reader = new FileReader();
reader.onloadend = showImage;
reader.readAsDataURL(file);
}
function showImage(e) {
$("#playerImage").attr("src", e.target.result);
$("#droplabel").html("Done");
}
});
HTML is straight-forward (I took the lines that include the scripts for simplicity):
<html>
<body>
<img id="playerImage"/>
<div id="dropimage">
<span id="droplabel">Drop file here...</span>
</div>
</body>
</html>
Also, if I try to change the dropbox.addEventListener for jQuery's $.bind, it doesn't do anything at all. Any thoughts?
The problem was that I was opening the html as a file. Chrome doesn't like that, so I resolved the problem by placing my html file in the wwwroot folder and opening it using a localhost/dnd.html address.