jQuery Validate File Type On Change - javascript

I have a jQuery File Upload. That upload function is only allow image type. .jpg, .gif, .png
Assume I have 2 file, that's a.jpg & b.pdf. Now, I change the extension b.pdf to be b.jpg
a.jpg is original image.
b.jpg is not an original image.
My question, how can I validate that b.jpg is not an original image?
Here is my JS script :
$(function()
{
$("#file").change(function()
{
var file = this.files[0];
var imagefile = file.type;
var match= ["image/jpeg","image/png","image/jpg"];
var file_size = this.files[0].size;
if(!((imagefile==match[0]) || (imagefile==match[1]) || (imagefile==match[2])))
{
alert("Invalid File");
}
else
{
var reader = new FileReader();
reader.onload = imageIsLoadeds;
reader.readAsDataURL(this.files[0]);
}
function imageIsLoadeds(e)
{
if(file_size>=1024000)
{
alert("File Size Error");
}
else
{
$('#image').attr('src', e.target.result);
}
}
}
}

You have to validate the MIME Type of the content being uploaded.
First select the required MIME type (Reference: http://www.freeformatter.com/mime-types-list.html).
Second you can use jQuery Validation Plugin to verify the MIME type of the uploaded content. (Reference: http://jqueryvalidation.org/accept-method/)

Related

Sorting JavaScript generated image preview into filename numeric order (files are 1-xxx, 2-xxx etc)

Using a JS snippet I found here I am able to preview images prior to upload, here is that code...
function previewImages() {
var preview = document.querySelector('#preview');
if (this.files) {
[].forEach.call(this.files, readAndPreview);
}
function readAndPreview(file) {
// Make sure `file.name` matches our extensions criteria
if (!/\.(jpe?g|png|gif)$/i.test(file.name)) {
return alert(file.name + " is not an image");
} // else...
var reader = new FileReader();
reader.addEventListener("load", function() {
var image = new Image();
image.height = 85;
image.title = file.name;
image.src = this.result;
preview.appendChild(image);
});
reader.readAsDataURL(file);
}
}
document.querySelector('#file-input').addEventListener("change", previewImages);
<input id="file-input" type="file" multiple>
<div id="preview"></div>
My issue is despite the filenames of the images being uploaded being like 1-black, 2-red, 3-blue etc when they are previewed they are in a random order, the desired output would be to show them in alphabetical order.
I have been looking at images.sort(); // use sort function of javascript. but can't figure out how to use it!

Make HTML5 FileReader working with heic files

When reading a file from the input element by the FileReader api it works, but my android device also allows sending files and it seems to send heic files anyway which then results in an empty image without any errors in the console. Also the orientation is wrong when getting an image directly from the camera. I just found heavy librarys to implement and i am looking for a smarter solution.
JavaScript
function previewFile( e ) {
var preview = document.getElementById('usersProfilePicture');
var file = e.files[0];
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
HTML5
<form>
<label>
<input id="uploadProfilePicture" name=file type=file accept="image/jpg, image/jpeg, image/png, image/gif, image/bmp">
</label>
</form>
There are no error messages at all. Firefox, Chrome both on desktop and android allow .heic files no matter what accept attribute i set.
worst solution: deny acceptance of .heic files
best solution: make fileReader work with .heic files.
in between solution: detect heic and convert it to jpeg, clientside.
The answer above explains this very well but for anyone looking for another example I have slightly modified the example from Heic2Any (https://alexcorvi.github.io/heic2any/)
<input type="file" id="heic" onchange="convertHEIC(event)">
async function convertHEIC (event){
let output = document.getElementById('output');
//if HEIC file
if(event.target.files[0] && event.target.files[0].name.includes(".HEIC")){
// get image as blob url
let blobURL = URL.createObjectURL(event.target.files[0]);
// convert "fetch" the new blob url
let blobRes = await fetch(blobURL)
// convert response to blob
let blob = await blobRes.blob()
// convert to PNG - response is blob
let conversionResult = await heic2any({ blob })
// convert to blob url
var url = URL.createObjectURL(conversionResult);
document.getElementById("target").innerHTML = `<a target="_blank" href="${url}"><img src="${url}"></a>`;
}
};
I have a workaround for this issue for now by using the library heic2any
(https://github.com/alexcorvi/heic2any)
check to see if file from input is .heic, then use library like so:
heic2any({
// required: the HEIF blob file
blob: file,
// (optional) MIME type of the target file
// it can be "image/jpeg", "image/png" or "image/gif"
// defaults to "image/png"
toType: "image/jpeg",
// conversion quality
// a number ranging from 0 to 1
quality: 0.5
})
I wrap this call in a promise and then pass the result to the file reader:
// uploadHEIC is a wrapper for heic2any
uploadHEIC(heicFile).then(function (heicToJpgResult) {
var reader = new Filereader();
reader.onload = function () {
// Do what you want to file
}
reader.readAsArrayBuffer(heicToJpgResult);
}
A few things to note to get this working properly.
First, in windows the assigned mime type for heic and heif is blank. Not sure when this bug will get fixed, but for now you can't rely on mime type in your scripts or input tag. I needed to add the heic and heif file extensions in the accept parameter of my input tag:
<input type="file" accept="image/*,.heic,.heif" />
and in my script I created a function to check the file extension for heic and heif if mime type was blank.
function isHEIC(file) { // check file extension since windows returns blank mime for heic
let x = file.type ? file.type.split('image/').pop() : file.name.split('.').pop().toLowerCase();
return x == 'heic' || x == 'heif';
}
Also, heic2any is pretty large (even if minified and compressed). I decided to load it dynamically only when needed.
function loadScript(url, callback) {
var script = document.querySelectorAll('script');
for (var i = 0; i < script.length; i++) {
if (script[i].src === url) {
script = script[i];
if (!script.readyState && !script.onload) {
callback();
} else { // script not loaded so wait up to 10 seconds
var secs = 0, thisInterval = setInterval(function() {
secs++;
if (!script.readyState && !script.onload) {
clearInterval(thisInterval);
callback();
} else if (secs == 10) {
clearInterval(thisInterval);
console.log('could not load ' + url);
}
}, 1000);
}
return;
}
}
script = document.createElement('script');
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
if (script.readyState) {
script.onreadystatechange = function() {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
callback();
}
}
} else {
script.onload = function() {
script.onload = null;
callback();
}
}
script.src = url;
}
I my use case I'm leveraging heic2any to prepare images for upload. If the image is heic I convert it to png (blob), then pass the result to another utility (image blob reduce) to resize and sharpen before converting to jpg in preparation for upload. However, for the sake of simplicity the example below uses heic2any to convert to jpg in 1 step before upload.
function convertHEIC(file) {
return new Promise(function(resolve) {
if (!isHEIC(file)) return resolve(file);
loadScript('https://cdn.jsdelivr.net/npm/heic2any#0.0.3/dist/heic2any.min.js', function() {
heic2any({
blob: file,
toType: "image/jpg"
}).then(function (convertedFile) {
convertedFile.name = file.name.substring(0, file.name.lastIndexOf('.')) + '.jpeg';
resolve(convertedFile);
});
});
});
}
// convert any heic (and do any other prep) before uploading the file
convertHEIC(file).then(function(file) {
// code to upload (or do something else with file)
.
.
.
}

How to submit base64 string of an uploaded image using only jquery

Here are the jquery codes that i've written
$(function(){
// Prepare the preview for profile picture
$("#profile_image").change(function(){
$("#message").empty(); // To remove the previous error message
var file = this.files[0];
var imagefile = file.type;
var match= ["image/jpeg","image/png","image/jpg"];
if(!((imagefile==match[0]) || (imagefile==match[1]) || (imagefile==match[2])))
{
$('#wizardPicturePreview1').attr('src','/images/houses/default.png');
$("#message").html("<p id='error'>Please Select A valid Image File</p>"+"<h4>Note</h4>"+"<span id='error_message'>Only jpeg, jpg and png Images type allowed</span>");
return false;
}
else
{
var reader = new FileReader();
reader.onload = function (e) {
$('#wizardPicturePreview1').attr('src', e.target.result).fadeIn('slow');
//getting the base64 string of the uploaded image
var imageso = e.target.result;
console.log('Encoded image:', imageso);
};
reader.readAsDataURL(this.files[0]);
}
});
$('form').submit(function() {
// submit the encoded base64 string of the uploaded image
$('.hidden-image-data').val(imageso);
var formValue = $(this).serialize();
$('#result-data').text(formValue);
// Prevent the form from actually submitting
return true;
});
});
I am getting the encoded image in console with the imageso variable in the change() function but it is nullable In the submit() function, the console tells me that the imageso variable is not declared while it is already declared. The problem is, how to get that base64 string of the uploaded image in the submit funtion using only JQuery without using Ajax?
imageso is outside the scope of the submit handler, you won't be able to access the variable as a result.
You will have to bring imageso into the submit scope.
I'd recommend to try and store it in the sessionStorage:
$(function(){
// Prepare the preview for profile picture
$("#profile_image").change(function(){
$("#message").empty(); // To remove the previous error message
var file = this.files[0];
var imagefile = file.type;
var match= ["image/jpeg","image/png","image/jpg"];
if(!((imagefile==match[0]) || (imagefile==match[1]) || (imagefile==match[2])))
{
$('#wizardPicturePreview1').attr('src','/images/houses/default.png');
$("#message").html("<p id='error'>Please Select A valid Image File</p>"+"<h4>Note</h4>"+"<span id='error_message'>Only jpeg, jpg and png Images type allowed</span>");
return false;
}
else
{
var reader = new FileReader();
reader.onload = function (e) {
$('#wizardPicturePreview1').attr('src', e.target.result).fadeIn('slow');
//getting the base64 string of the uploaded image
var imageso = e.target.result;
sessionStorage.setItem("imageso", imageso);
console.log('Encoded image:', imageso);
};
reader.readAsDataURL(this.files[0]);
}
});
$('form').submit(function() {
// submit the encoded base64 string of the uploaded image
$('.hidden-image-data').val(sessionStorage.getItem("imageso"));
var formValue = $(this).serialize();
$('#result-data').text(formValue);
// Prevent the form from actually submitting
return true;
});
Thx Saravenan N, i've found the answer. Declare imageso after the document ready function
$(function(){
var imageso;
// Prepare the preview for profile picture
$("#profile_image").change(function(){
$("#message").empty(); // To remove the previous error message
var file = this.files[0];
var imagefile = file.type;
var match= ["image/jpeg","image/png","image/jpg"];
if(!((imagefile==match[0]) || (imagefile==match[1]) || (imagefile==match[2])))
{
$('#wizardPicturePreview1').attr('src','/images/houses/default.png');
$("#message").html("<p id='error'>Please Select A valid Image File</p>"+"<h4>Note</h4>"+"<span id='error_message'>Only jpeg, jpg and png Images type allowed</span>");
return false;
}
else
{
var reader = new FileReader();
reader.onload = function (e) {
$('#wizardPicturePreview1').attr('src', e.target.result).fadeIn('slow');
//getting the base64 string of the uploaded image
imageso = e.target.result;
console.log('Encoded image:', imageso);
};
reader.readAsDataURL(this.files[0]);
}
});
$('form').submit(function() {
// submit the encoded base64 string of the uploaded image
$('.hidden-image-data').val(imageso);
var formValue = $(this).serialize();
$('#result-data').text(formValue);
// Prevent the form from actually submitting
return true;
});
});

How to get base64 from input file in IE without using FileReader or HTML5

I hope I can have help from you. I need to get a file from an HTML input file element.
This is the HTML:
<input type="file" name="allegatoImg" id="allegatoImg" onchange="javascript:readURL(this)"/>
And this is JavaScript:
function readURL(input) {
var mimeType;
if (window.FileReader) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
var dataURL = e.target.result;
mimeType = dataURL.split(",")[0].split(":")[1].split(";")[0];
if (mimeType == 'image/jpeg') {
jQuery('#imgallegato').attr('src', e.target.result);
//jQuery('#fotoTemp').attr('src', e.target.result);
provaInvioImgSrcToServer();
} else {
alert('Errore nella lettura del file. Controllare che sia stato caricato un file con estensione jpeg.');
return;
}
};
reader.readAsDataURL(input.files[0]);
}
} else {
f = document.dettRichAbbForm;
document.getElementById("imgallegato").src = "file:///" + input.value;
var estensione = ctrlExtensionFileIE(input.value);
alert('path file = ' + jQuery("#imgallegato").attr('src') );
if (estensione=='jpg' || estensione=='jpeg') {
provaInvioImgSrcToServer();
} else {
alert('Error in reading file');
return;
}
}
}
function provaInvioImgSrcToServer() {
var urlToCall = provaInvioImgSrcToServerUrl;
alert('img path = ' + jQuery("#imgallegato").attr('src'));
jQuery.ajax({
cache : false,
type : "POST",
timeout : 5000,
url : urlToCall,
data : {imgSource: jQuery("#imgallegato").attr('src')},
success : function(result) {
ritagliaImg();
},
error : function(errorMsg) {
//gestAjaxCallError(errorMsg, divResultBodId, divResultBodId);
alert('Errore nel caricamento dell\'immagine selezionata.');
}
});
}
function ctrlExtensionFileIE(value) {
var splittedVal = value.split(".");
return splittedVal[1];
}
I'm working on Liferay 5.1 with an old version of jQuery so I can't use HTML5 with canvas element, because I should load the image from the input file into a Jcrop element.
My problem is linked to this part of the code:
f = document.dettRichAbbForm;
document.getElementById("imgallegato").src = "file:///" + input.value;
FileReader works fine in Mozilla, Chrome and IE10+, but with IE9- I should use the code above.
The problem is that input.value returns the path of the selected file and I need to get the base64 in order to send it to the server. I can't do the submit of my form, because this approach needs to re-load my jsp and I have others fields.
Is there someone that could help me to get the byte array from selected file on IE without using canvas element, HTML5 and FileReader library?

Read CSV file with Javascript into a key value pair array

There are plenty of examples of reading a CSV file using jQuery however javascript examples are few and far between.
As i am using an internal script editor for a particular application, i am limited to using Javascript only.
I have a csv file that has headings followed by data in each row.
Heading1,Heading2,Heading3,Heading4
row1data1,row1data2,row1data3,row1data4
row2data1,row2data2,row2data3,row2data4
The delimiter being used is , however there could be others e.g. ^.
As i can't upload a file, i have the option to manually reference an absolute path.
Is there a way i can use only javascript to read a csv file?
As a start, here is a couple of ways to read a file with javascript
HttpRequest: (from web server or absolute path)
Source: Javascript - read local text file
function readTextFile(file)
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
alert(allText);
}
}
}
rawFile.send(null);
}
And specify file:// in your filename when using an absolute path
readTextFile("file:///C:/your/path/to/file.txt");
FileReader API:
Source:
- http://codepen.io/matt-west/pen/KjEHg
- http://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api
HTML
<div id="page-wrapper">
<h1>Text File Reader</h1>
<div>
Select a text file:
<input type="file" id="fileInput">
</div>
<pre id="fileDisplayArea"><pre>
</div>
JS
window.onload = function() {
var fileInput = document.getElementById('fileInput');
var fileDisplayArea = document.getElementById('fileDisplayArea');
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(e) {
fileDisplayArea.innerText = reader.result;
}
reader.readAsText(file);
} else {
fileDisplayArea.innerText = "File not supported!"
}
});
}
JS on MS Windows (simple sample)
Source: http://msdn.microsoft.com/en-us/library/czxefwt8(v=vs.84).aspx
function ReadFiles()
{
var fso, f1, ts, s;
var ForReading = 1;
fso = new ActiveXObject("Scripting.FileSystemObject");
ts = fso.OpenTextFile("c:\\testfile.txt", ForReading);
s = ts.ReadLine();
// s holds the text content
ts.Close();
}

Categories

Resources