Jquery Image preview error - javascript

The requirement:
I am trying preview an image before uploading. So I come up with this code:
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]);
}
}
And I am calling the function by this method:
$(document).ready(function(){
$('#image').on('change',function(e){
readURL(this);
});
});
The code is working fine. Now the HTML is this:-
<div class="control-group">
<label class="control-label" for="fileInput"><?php echo ucfirst($entity); ?> Image :</label>
<div class="controls">
<input class="input-file uniform_on" name="image" id="image" type="file"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="fileInput">Image Preview:</label>
<div class="controls">
<img src="#" name="preview" id="preview" height="100" alt="Preview Image"/>
</div>
</div>
Till now the code is running smooth.
Now I want to update my code based on these requirements:-
First the imageSize will be checked, whether it's less than 300KB.
Then it will check if the dimension is less than 1200x1200
If the file is less than 300KB and size less than 1200x1200, then the preview will be displayed.
So I made the following changes:-
var maxImageSize = parseInt(3000) * 100; //3KB * 100 = 300KB
var maxImageWidth = 1200;
var maxImageHeight = 1200;
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]);
}
}
$(document).ready(function(){
$('#image').on('change',function(e){
var imageSize = this.files[0].size;
if(imageSize > maxImageSize)
{
if(maxImageSize>=1000 && maxImageSize<1000000)
{
var allowedSize = parseFloat(parseInt(maxImageSize)/1000)+' KB';
}
else if(maxImageSize>=1000000)
{
var allowedSize = parseFloat(parseInt(maxImageSize)/1000000)+' MB';
}
var $el = $('#image');
$el.wrap('<form>').closest('form').get(0).reset();
$el.unwrap();
var html = '<strong>Severe Error</strong><p>Max. filesize allowed is '+allowedSize+'</p>';
$('#modalError').html(html);
$('#modalError').show();
$('#modal').modal();
}
else
{
var imgFile = this.files[0];
var img = new Image();
img.src = window.URL.createObjectURL(imgFile);
img.onload = function() {
var imgField = $('#image');
var imgWidth = img.naturalWidth, imgHeight = img.naturalHeight;
if(imgWidth>maxImageWidth && imgHeight>maxImageHeight)
{
var html = '<strong>Severe Error</strong><p>Max. width allowed is '+maxImageWidth+'px & Max. height allowed is '+maxImageHeight+'px</p>';
$('#modalError').html(html);
$('#modalError').show();
$('#modal').modal();
}
else
{
readURL(imgField);
}
};
}
});
});
In the above code, the size and dimension validation is working fine. However, the image is not getting previewed.
What am I doing wrong?

You are passing an <img> to readURL instead of a File object at readURL(imgField)

Related

How can I display the file name of the image I am loading in a new div?

I have a file input that I'm using to display image thumbnails. When you click on a thumbnail, the image appears in a separate div. That part is working fine, but I would also like the name of the file to be displayed under the larger image. I used this great guide for displaying multiple image thumbnails. I have two event listeners, one for load and one for click. I tried to add document.getElementById('right').innertext=this.title; in the click event, but it just doesn't seem to do anything.
Below is my complete code:
<div id="left">
<input id="files" type="file" onchange="previewFiles()" multiple />
<hr>
<div id="preview"></div>
</div>
<div id="right">
<img src="" id="img2" style="max-width: 500px;">
<p></p>
</div>
<script>
function previewFiles() {
var preview = document.querySelector('#preview');
var files = document.querySelector('input[type=file]').files;
function readAndPreview(file) {
var reader = new FileReader();
reader.addEventListener("load", function () {
var image = new Image();
image.height = 50;
image.title = file.name;
image.id = Math.floor(Math.random() * 100);
image.src = this.result;
image.addEventListener("click", function() {
document.getElementById('img2').src = this.src;
document.getElementById('right').innertext=this.title;
})
preview.appendChild(image);
}, false);
reader.readAsDataURL(file);
}
if (files) {
[].forEach.call(files, readAndPreview);
}
}
</script>
You mean this?
it is innerText with a capital T and you want it in the p tag?
function previewFiles() {
var preview = document.querySelector('#preview');
var files = this.files;
function readAndPreview(file) {
var reader = new FileReader();
reader.addEventListener("load", function() {
var image = new Image();
image.height = 50;
image.title = file.name;
image.id = Math.floor(Math.random() * 100);
image.src = this.result;
image.addEventListener("click", function() {
document.getElementById('img2').src = this.src;
document.querySelector('#right p').innerText = this.title;
})
preview.appendChild(image);
}, false);
reader.readAsDataURL(file);
}
if (files) {
[].forEach.call(files, readAndPreview);
}
}
document.querySelector('input[type=file]').addEventListener("change",previewFiles)
<div id="left">
<input id="files" type="file" multiple />
<hr>
<div id="preview"></div>
</div>
<div id="right">
<img src="" id="img2" style="max-width: 500px;">
<p></p>
</div>
</script>

Chrome bug related to .naturalWidth?

It seems that the below code randomly produces aImg.naturalWidth either the real width of the picture or 0. Is it a Chrome 70.0.3538.67 for Linux bug?
If it is not a bug, how to make it work right (not to return 0)?
function handleImageFile(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (file.type != 'image/jpeg') continue;
var img = document.createElement("img");
img.file = file;
var reader = new FileReader();
reader.onload = (function(aImg) {
return function(e) {
$('#newPictureContainer').css('display', 'block');
document.getElementById('newPicture').appendChild(img);
aImg.src = e.target.result;
if (aImg.naturalWidth >= 300 || aImg.naturalHeight >= 300) {
if (aImg.naturalWidth <= aImg.naturalHeight)
aImg.width = 300;
else
aImg.height = 300;
$('#selectPicture').css('display', 'none');
} else {
$('#selectPicture [type=file]').val("");
alert("The smallest side of the picture should be at least 300 pixels.");
}
};
})(img);
reader.readAsDataURL(file);
}
}
<div id="selectPicture" style="display:block">
<input type="file" name="imageUpload" onchange="handleImageFile(this.files)"/>
</div>
<div id="newPictureContainer" style="display:none">
<span id="newPicture"></span>
<img src="/include/javascript/israelinfo/multiuploader/images/cross-small.gif"
width="16" height="16" title="Удалить" alt="Delete" class="MUdelete"
onclick="closePicture()">
</div>
#JᴀʏMᴇᴇ gave an answer:
I must access .naturalWidth in a handler of onload of the image not one of FileReader.
I mistakenly assumed that the image is loaded immediately after assigning a data: URL to .src. It seems not to be the case.

Javascript - if boolean true not working

So, i created the following function to check the file uploaded by user is
1) Image only
2) Size less than maxSize KBs
3) Dimensions less than maxWidth and maxHeight
All else is working fine except that the condition where I check dimensions. The value in dimensions is indeed the correct value but the condition if(dimensions) doesn't run even when dimensions=true.
Is there something I am doing wrong?
var maxThumbnailWidth = '1050';
var maxThumbnailHeight = '700';
var maxThumbnailSize = '60';
function imageFileChecks(file, type) // type here refers to either Image or Banner or Thumbnail
{
var maxSize;
var maxWidth;
var maxHeight;
var dimensions = false;
if (type == 'image') {
maxSize = maxImageSize;
maxWidth = maxImageWidth;
maxHeight = maxImageHeight;
}
if (type == 'banner') {
maxSize = maxBannerSize;
maxWidth = maxBannerWidth;
maxHeight = maxBannerHeight;
}
if (type == 'thumbnail') {
maxSize = maxThumbnailSize;
maxWidth = maxThumbnailWidth;
maxHeight = maxThumbnailHeight;
}
//First check file type.. Allow only images
if (file.type.match('image.*')) {
var size = (file.size / 1024).toFixed(0);
size = parseInt(size);
console.log('size is ' + size + ' and max size is ' + maxSize);
if (size <= maxSize) {
var img = new Image();
img.onload = function() {
var sizes = {
width: this.width,
height: this.height
};
URL.revokeObjectURL(this.src);
//console.log('onload sizes', sizes);
console.log('onload width sizes', sizes.width);
console.log('onload height sizes', sizes.height);
var width = parseInt(sizes.width);
var height = parseInt(sizes.height);
if (width <= maxWidth && height <= maxHeight) {
dimensions = true;
console.log('dimensions = ', dimensions);
}
}
var objectURL = URL.createObjectURL(file);
img.src = objectURL;
if (dimensions) {
alert('here in dimensions true');
sign_request(file, function(response) {
upload(file, response.signed_request, response.url, function() {
imageURL = response.url;
alert('all went well and image uploaded!');
return imageURL;
})
})
} else {
return errorMsg = 'Image dimensions not correct!';
}
} else {
return errorMsg = 'Image size not correct!';
}
} else {
return errorMsg = 'Image Type not correct!';
}
}
<div class="form-group">
<label class="col-md-6 col-xs-12 control-label">Thumbnail</label>
<div class="col-md-6 col-xs-12">
<input type="file" id="thumbnail" class="file" required>
<br>
</div>
</div>
<script type="text/javascript">
document.getElementById('thumbnail').onchange = function() {
var file = document.getElementById('thumbnail').files[0];
if (!file) {
console.log("ji");
return;
}
var type = 'thumbnail';
var thumbnailURL = imageFileChecks(file, type);
}
</script>
This seems like an async issue -- your if(dimensions) statement is running before your img.onload function finishes, in which case dimensions would be equal to false when you get to that part in your code, despite the img.onload function and its logic executing correctly.
You could try nesting the if(dimensions) condition in the img.onload function.
You set your dimension property inside the img.onload callback function.
This will not be executed directly. Then you check the value directly below, which will not be set yet. This is the nature of JavaScript: async functions being queued up to run at some time (example when an image finished loading).
To solve your problem, you need to make the rest of your function execute after img load. This can be done with either callback functions or promises.
I would read up on the asynchronous behavior a bit. Sorry for not providing a link, but should be plenty out there!
#William is right.You can handle it like that
function loadImage(src,callback){
var img = new Image();
img.onload = function() {
if (callback) {
callback(img);
}
}
img.src = src;
}

Uploading image and displaying it small with javascript

So, I've got this working javascript and it loads an image that a user uploads to the HTML on the screen displaying it.
But, it displays the image without a max height or width so it moves buttons on the page to where they can't be seen or pressed. This includes the submit button if the image uploaded is big enough.
So, is there some way to make the 'uploaded' image display really small: like max 30px in height?
$(function(){
$('#user_avatar').change(function(e){
var files = event.target.files;
var image = files[0];
for (var i = files.length - 1; i >= 0; i--) {
var reader = new FileReader();
var file = files[i];
reader.onload = function(file) {
var img = new Image();
img.src = file.target.result;
$('#inputpic').attr('src', file.target.result);
}
reader.readAsDataURL(image);
};
});
});
I have tried adding:
theimage = getElementById('inputpic')
theimage.style.height='10px';
But this had no effect.
EDIT 1
html.slim that the JS talks to:
= image_tag('temp.png', id: "inputpic", class: 'tiny_image_display')
SCSS that I made:
.tiny-image-display {
max-height: 30px;
}
You can set this in CSS very easily:
#inputpic {
max-height: 30px;
}
$(function(){
$('#user_avatar').change(function(e){
var files = event.target.files;
var image = files[0];
for (var i = files.length - 1; i >= 0; i--) {
var reader = new FileReader();
var file = files[i];
reader.onload = function(file) {
var img = new Image();
img.src = file.target.result;
img.height = "30";
$('#inputpic').attr('src', file.target.result);
}
reader.readAsDataURL(image);
};
});
});

How to show a 'X' mark on a image preview

I've this upload image preview code:
function readURL(input) {
$.each(input.files,function(i) {
var reader = new FileReader();
reader.onload = function (e) {
var container = $('#preview_drop');
var image = $('<img>').attr('src', e.target.result).attr('id', 'preimg')
image.appendTo(container);
$("#add_photoajax").mCustomScrollbar("update");
};
reader.readAsDataURL(input.files[i]);
});
}
How can i show a 'x' mark or a delete.png on each previewed image?
'''
var container = $('#preview_drop');
//Create it first
var x = $('<img>').attr('src', 'delete.png');
var image = $('<img>').attr('src', e.target.result).attr('id', 'preimg')
image.appendTo(container);
//and then append it after/before img
x.appendTo(container);
$("#add_photoajax").mCustomScrollbar("update");
...

Categories

Resources