File type validation with JavaScript - javascript

I have a question regarding to JavaScript validation. I am validaing the <input type="file"> whenever my scripts runs, it validates but also the action page is called. I want to stop the action page until the validation is complete. Here is my code, any help will be awesome. Regards
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Image Uploading</title>
</head>
<body>
<form name="xx" action="server.php" method="post" enctype="multipart/form-data" onsubmit="Checkfiles(this)">
<input type="file" name="file_uploading" id="filename">
<input type="submit" value="Submit" name="uploadfile">
</form>
<form name="view" method="post">
View your uploaded Images
</form>
</body>
</html>
<script type="text/javascript">
function Checkfiles() {
var fup = document.getElementById('filename');
var fileName = fup.value;
var ext = fileName.substring(fileName.lastIndexOf('.') + 1);
if(ext =="GIF" || ext=="gif") {
return true;
} else {
alert("Upload Gif Images only");
return false;
}
}
</script>

var fname = "the file name here.ext";
var re = /(\.jpg|\.jpeg|\.bmp|\.gif|\.png)$/i;
if (!re.exec(fname)) {
alert("File extension not supported!");
}

File Extension Validation through javascript
function ValidateExtension() {
var allowedFiles = [".doc", ".docx", ".pdf"];
var fileUpload = document.getElementById("fileUpload");
var lblError = document.getElementById("lblError");
var regex = new RegExp("([a-zA-Z0-9\s_\\.\-:])+(" + allowedFiles.join('|') + ")$");
if (!regex.test(fileUpload.value.toLowerCase())) {
lblError.innerHTML = "Please upload files having extensions: <b>" + allowedFiles.join(', ') + "</b> only.";
return false;
}
lblError.innerHTML = "";
return true;
}
onclick event of submit button call this javascript function.
With the help of ID = lblError , print the error message in html section.

You can use the File Api to test for magic number. Maybe take a look at this answer for other ideas about the validation. More reliable than the file extension check.

The return value of the submit handler affects the submission.
onsubmit="return Checkfiles();"
This is basically saying:
form.onsubmit = function () { return Checkfiles(); };

In general, you can use JavaScript some() method for that.
function isImage(icon) {
const ext = ['.jpg', '.jpeg', '.bmp', '.gif', '.png', '.svg'];
return ext.some(el => icon.endsWith(el));
}
const fname = "filename.ext";
if (!isImage(fname)) {
console.log("File extension not supported!");
}

You need to return CheckFiles()

Upload bulk data through excel sheet(.csv)
$("form").submit(function(){
var val = $(this).val().toLowerCase();
var regex = new RegExp("(.*?)\.(csv)$");
if(!(regex.test(val))) {
$(this).val('');
alert('Only csv file can be uploaded');
return false;
}
});

var _URL = window.URL || window.webkitURL;
$("input[type=file]").change(function(e) {
var file;
if ((file = this.files[0])) {
var img = new Image();
img.onload = function () {
// do to on load
};
img.onerror = function () {
alert("valid format " + file.type);
};
img.src = _URL.createObjectURL(file);
}
});

The fileValidation() function contains the complete file type validation code. This JavaScript function needs to call for file extension validation.
HTML
<!-- File input field -->
<input type="file" id="file" onchange="return fileValidation()"/>
<!-- Image preview -->
<div id="imagePreview"></div>
JavaScript
function fileValidation(){
var fileInput = document.getElementById('file');
var filePath = fileInput.value;
var allowedExtensions = /(\.jpg|\.jpeg|\.png|\.gif)$/i;
if(!allowedExtensions.exec(filePath)){
alert('Please upload file having extensions .jpeg/.jpg/.png/.gif only.');
fileInput.value = '';
return false;
}else{
//Image preview
if (fileInput.files && fileInput.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById('imagePreview').innerHTML = '<img src="'+e.target.result+'"/>';
};
reader.readAsDataURL(fileInput.files[0]);
}
}
}
fileValidation()

> html
<input type="file" id="userfile" name="userfile" value="" class="form-control userfile" required>
> javascript
$(document).on('change', '.userfile', function (e) {
e.preventDefault();
const thisValue = $(this).val().split('.').pop().toLowerCase();
const userFile = [thisValue];
// Allowing file type
const validFile = ['csv', 'xlsx'];
// const intersection = validFile.filter(element => userFile.includes(element));
// if(intersection == ''){
// $(this).val('');
// alert('Please Select ' + validFile + ' file');
// return false;
// }
// Allowing file type
const allowedExtensions = /(\.csv|\.xlsx)$/i;
if (!allowedExtensions.exec($(this).val())) {
$(this).val('');
alert('Please Select ' + validFile + ' file');
return false;
}
});

Related

Check file extension and alert user if isn't image file using javascript

When i upload multiple images and one of them which is not valid extension and message should be shown File type is not valid and when I upload images one by one it works perfect please help me how can resolve that ? thank u
javascript
$("input[type=file]").on('change', function(){
//Get uploaded file extension
var extension = $(this).val().split('.').pop().toLowerCase();
// Create array with the files extensions that we wish to upload
var validFileExtensions = ['jpeg', 'jpg', 'png'];
//Check file extension in the array.if -1 that means the file extension is not in the list.
if ($.inArray(extension, validFileExtensions) == -1) {
$('#filetype').text("File type is not valid").show();
$('#btnSubmit').prop('disabled', true);
}
});
With the multiple attribute added to the input HTML tag, iterate the files property on the input element in the change event listener.
document.addEventListener('DOMContentLoaded', function () {
document.querySelector("input").addEventListener("change", changeHandler);
});
function changeHandler() {
const validFileExtensions = ['jpeg', 'jpg', 'png'];
// 'this' refers to the 'input' HTML element
// Assigning 'this' to the 'element' variable is not
// necessary but assigned here for code readability.
let element = this;
// Check if the element has a FileList before checking each file
if (element.files && element.files.length) {
for (i = 0; i < element.files.length; i++) {
const file = element.files[i];
const filename = file.name;
const extension = filename.split('.').pop();
if (validFileExtensions.includes(extension)) {
console.log("VALID file -> " + filename);
}
else {
console.log("INVALID file -> " + filename);
}
}
}
}
<input type="file" multiple />
Applying the code above to your jQuery code:
$("input[type=file]").on('change', function() {
//Get uploaded file extension
var extension = $(this).val().split('.').pop().toLowerCase();
// Create array with the files extensions that we wish to upload
var validFileExtensions = ['jpeg', 'jpg', 'png'];
//Check file extension in the array.if -1 that means the file extension is not in the list.
if ($.inArray(extension, validFileExtensions) == -1) {
$('#filetype').text("File type is not valid").show();
$('#btnSubmit').prop('disabled', true);
}
// Check if the element has a FileList before checking each file
if (this.files && this.files.length) {
var message = "";
for (i = 0; i < this.files.length; i++) {
var file = this.files[i];
var filename = file.name;
var extension = filename.split('.').pop();
if (!validFileExtensions.includes(extension)) {
message += filename + " is not a valid file type. ";
}
}
if (message !== "") {
$('#filetype').text(message).show();
$('#btnSubmit').prop('disabled', true);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" id="fileInput" multiple>
<span id="filetype"></span>
<button type="submit">Upload</button>
const fileInput = document.querySelector('input[type="file"]');
const submitBtn = document.querySelector('button[type="submit"]');
submitBtn.disabled = true;
fileInput.addEventListener('change', () => {
const fileName = fileInput.value;
const fileType = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
if (fileType !== 'jpg' && fileType !== 'jpeg' && fileType !== 'png' && fileType !== 'gif') {
alert('File is not an image');
fileInput.value = '';
submitBtn.disabled = true; // Disable the submit button
} else {
submitBtn.disabled = false; // Enable the submit button
}
});
.fileInput{
text-align:center;
margin-top:10%;
}
<div class="fileInput">
<input type="file" id="fileInput">
<button type="submit">Upload</button>
</div>

Change Event is not working on input field

I'm trying to debug and find the error, why Change Event is not working on input field. so i have put breakpoint on change event of jquery while debugging but it skip that .i am not able to find why it is not stopping at breakpoint for debugging.
html part which is generated dynamically only a part is shown here.
var p = $('<input type="file" ID="flImage" name="flImage" runat="server" />');
$("#mainTbl").append(p);
script
<script type="text/javascript">
$(function () {
var reader = new FileReader();
var fileName;
var contentType;
//tried all three trick to envoke change function but not work
//$('input[name=flImage]').change(function () {
$("<input type='file' name='flImage' ID='flImage'/>").change(function () {
//$("input[name=flImage]").on("change", function(){
if (typeof (FileReader) != "undefined") {
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.jpg|.jpeg|.gif|.png|.bmp)$/;
$($(this)[0].files).each(function () {
var file = $(this);
if (regex.test(file[0].name.toLowerCase())) {
fileName = file[0].name;
contentType = file[0].type;
reader.readAsDataURL(file[0]);
} else {
alert(file[0].name + " is not a valid image file.");
return false;
}
});
} else {
alert("This browser does not support HTML5 FileReader.");
}
});
</script>
After show many advice from comment i'm trying like this to access input element
is it ok :div.main main-raised > div#pdfFormInsideL1 > table#mainTbl > tbody >tr>'input[name=flImage]
image given below
var p = $('<input type="file" ID="flImage" name="flImage" runat="server" />');
$("#mainTbl").append(p);
$(function () {
var reader = new FileReader();
var fileName;
var contentType;
$("input[name=flImage]").on("change", function(){
if (typeof (FileReader) != "undefined") {
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.jpg|.jpeg|.gif|.png|.bmp)$/;
$($(this)[0].files).each(function () {
var file = $(this);
if (regex.test(file[0].name.toLowerCase())) {
fileName = file[0].name;
contentType = file[0].type;
reader.readAsDataURL(file[0]);
} else {
alert(file[0].name + " is not a valid image file.");
return false;
}
});
} else {
alert("This browser does not support HTML5 FileReader.");
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mainTbl"></div>

div used for image display causing difficulties while uploading file;

Here i have a image upload mechanism. It's purpose is to accept an image and display it in a div with id=imageholder . My problem is if i have this image holder div inside my form , it gives upload error (4) . So i get an empty $_FILES array. But if i omit it i get a populated $_FILES array .But i need that div inside the form for design purpose. How i can escape this situation .
with imagehoder div inside form:
without imageholder div :
code may seem long . But none of it is related to the question. It is generally for validating the mime type
full code :
<?php print_r($_FILES);?>
<html>
<body>
<form method='post' enctype='multipart/form-data' action="<?php echo $_SERVER['PHP_SELF'] ?>">
<div id='photouploder'>
<div id='imagehoder'></div> // creating problem
<div class="inputWrapper">upload image
<input class="fileInput" id='up' type="file" name="image"/>
</div>
</div>
<input type='submit' value='submit'>
</form>
<script>
var imageholder=document.getElementById('imageholder');
function getBLOBFileHeader(url, blob, callback,callbackTwo) {
var fileReader = new FileReader();
fileReader.onloadend = function(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for (var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
var imgtype= callback(url, header);// headerCallback
callbackTwo(imgtype,blob)
};
fileReader.readAsArrayBuffer(blob);
}
function headerCallback(url, headerString) {
var info=getHeaderInfo(url, headerString);
return info;
}
function getTheJobDone(mimetype,blob){
var mimearray=['image/png','image/jpeg','image/gif'];
console.log('mimetype is :'+mimetype);
if(mimearray.indexOf(mimetype) !=-1){
printImage(blob);
}else{
document.getElementById('up').value='';
while (imageholder.firstChild) {
imageholder.removeChild(imageholder.firstChild);
}
console.log('you can not upload this file type');
}
}
function remoteCallback(url, blob) {
getBLOBFileHeader(url, blob, headerCallback,getTheJobDone);
}
function printImage(blob) {
// Add this image to the document body for proof of GET success
var fr = new FileReader();
fr.onloadend = function(e) {
var img=document.createElement('img');
img.setAttribute('src',e.target.result);
img.setAttribute('style','width:100%;height:100%;');
imageholder.appendChild(img);
};
fr.readAsDataURL(blob);
}
function mimeType(headerString) {
switch (headerString) {
case "89504e47":
type = "image/png";
break;
case "47494638":
type = "image/gif";
break;
case "ffd8ffe0":
case "ffd8ffe1":
case "ffd8ffe2":
type = "image/jpeg";
break;
default:
type = "unknown";
break;
}
return type;
}
function getHeaderInfo(url, headerString) {
return( mimeType(headerString));
}
// Check for FileReader support
function fileread(event){
if (window.FileReader && window.Blob) {
/* Handle local files */
var mimetype;
var mimearray=['image/png','image/jpeg','image/gif'];
var file = event.target.files[0];
if(mimearray.indexOf(file.type)===-1 || file.size >= 2 * 1024 * 1024){
while (imageholder.firstChild) {
imageholder.removeChild(imageholder.firstChild);
}
document.getElementById('up').value='';
console.log("you can't upload this file type");
file=null;
return false;
}else{
while (imageholder.firstChild) {
imageholder.removeChild(imageholder.firstChild);
}
document.getElementById('up').value='';
remoteCallback(file.name, file);
}
}else {
// File and Blob are not supported
console.log('file and blob is not supported');
} /* Drakes, 2015 */
}
document.getElementById('up').addEventListener('change',fileread,false);
</script>
</body>
</html>
First of all: HTML attribute values should always be encapsulated in double quotes.
Second, this is a correct example of reading files using html5 API like you tried:
(Also check the documentation for it: https://developer.mozilla.org/en-US/docs/Web/API/FileReader)
window.onload = function() {
var fileInput = document.getElementById('up');
var fileDisplayArea = document.getElementById('imagehoder');
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var imageType = /image.*/;
if (file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function(e) {
fileDisplayArea.innerHTML = "";
var img = new Image();
img.src = reader.result;
fileDisplayArea.appendChild(img);
}
reader.readAsDataURL(file);
} else {
fileDisplayArea.innerHTML = "File not supported!"
}
});
}
<body>
<form method="post" enctype='multipart/form-data' action="<?php echo $_SERVER['PHP_SELF'] ?>">
<div id="photouploder">
<div id="imagehoder"></div>
<div class="inputWrapper">upload image
<input class="fileInput" id="up" type="file" name="image" />
</div>
</div>
<input type="submit" value="submit">
</form>
</body>
I'm not sure about the 'design purpose' in your question. If the 'design purpose' means UI design (CSS related), then probably this reason doesn't stand since they are totally irrelevant.
Also, the file upload technology is very mature now. There are bunches of open source implements in all languages and are well-tested and easy-to-use I highly recommend you to take a look at them before implementing it yourself.

Dropzone.js to get file URL

I have this function which generates the File URL using createobjectURL and works when I use the normal input file tag.
I am trying to implement the same using dropzone.js but when I drop the file it starts
showing the upload progress bar although I haven't defined any action.
How can i obtain the URL using dropzone.js?
Javascript
function localFileVideoPlayerInit(win) {
var URL = win.URL || win.webkitURL,
displayMessage = (function displayMessageInit() {
return function displayMessage() {
alert("error");
};
}()),
playSelectedFile = function playSelectedFileInit(event) {
var file = this.files[0];
var type = file.type;
var videoNode = document.querySelector('video');
var canPlay = videoNode.canPlayType(type);
canPlay = (canPlay === '' ? 'no' : canPlay);
if (canPlay === 'no') {
displayMessage();
}
}
};
var fileURL = URL.createObjectURL(file);
videoNode.src = fileURL;
},
inputNode = document.querySelector('input');
if (!URL) {
displayMessage('Your browser is not ' + 'supported!', true);
return;
}
inputNode.addEventListener('change', playSelectedFile, false);
}
HTML
<form action="" class="dropzone">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
</form>
Seems you would have to reference the variable fileURL, and use javascript to dynamically set the action of the form.

How to read text file in JavaScript

I am trying to load a text file into my JavaScript file and then read the lines from that file in order to get information, and I tried the FileReader but it does not seem to be working. Can anyone help?
function analyze(){
var f = new FileReader();
f.onloadend = function(){
console.log("success");
}
f.readAsText("cities.txt");
}
Yeah it is possible with FileReader, I have already done an example of this, here's the code:
<!DOCTYPE html>
<html>
<head>
<title>Read File (via User Input selection)</title>
<script type="text/javascript">
var reader; //GLOBAL File Reader object for demo purpose only
/**
* Check for the various File API support.
*/
function checkFileAPI() {
if (window.File && window.FileReader && window.FileList && window.Blob) {
reader = new FileReader();
return true;
} else {
alert('The File APIs are not fully supported by your browser. Fallback required.');
return false;
}
}
/**
* read text input
*/
function readText(filePath) {
var output = ""; //placeholder for text output
if(filePath.files && filePath.files[0]) {
reader.onload = function (e) {
output = e.target.result;
displayContents(output);
};//end onload()
reader.readAsText(filePath.files[0]);
}//end if html5 filelist support
else if(ActiveXObject && filePath) { //fallback to IE 6-8 support via ActiveX
try {
reader = new ActiveXObject("Scripting.FileSystemObject");
var file = reader.OpenTextFile(filePath, 1); //ActiveX File Object
output = file.ReadAll(); //text contents of file
file.Close(); //close file "input stream"
displayContents(output);
} catch (e) {
if (e.number == -2146827859) {
alert('Unable to access local files due to browser security settings. ' +
'To overcome this, go to Tools->Internet Options->Security->Custom Level. ' +
'Find the setting for "Initialize and script ActiveX controls not marked as safe" and change it to "Enable" or "Prompt"');
}
}
}
else { //this is where you could fallback to Java Applet, Flash or similar
return false;
}
return true;
}
/**
* display content using a basic HTML replacement
*/
function displayContents(txt) {
var el = document.getElementById('main');
el.innerHTML = txt; //display output in DOM
}
</script>
</head>
<body onload="checkFileAPI();">
<div id="container">
<input type="file" onchange='readText(this)' />
<br/>
<hr/>
<h3>Contents of the Text file:</h3>
<div id="main">
...
</div>
</div>
</body>
</html>
It's also possible to do the same thing to support some older versions of IE (I think 6-8) using the ActiveX Object, I had some old code which does that too but its been a while so I'll have to dig it up I've found a solution similar to the one I used courtesy of Jacky Cui's blog and edited this answer (also cleaned up code a bit). Hope it helps.
Lastly, I just read some other answers that beat me to the draw, but as they suggest, you might be looking for code that lets you load a text file from the server (or device) where the JavaScript file is sitting. If that's the case then you want AJAX code to load the document dynamically which would be something as follows:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" />
<title>Read File (via AJAX)</title>
<script type="text/javascript">
var reader = new XMLHttpRequest() || new ActiveXObject('MSXML2.XMLHTTP');
function loadFile() {
reader.open('get', 'test.txt', true);
reader.onreadystatechange = displayContents;
reader.send(null);
}
function displayContents() {
if(reader.readyState==4) {
var el = document.getElementById('main');
el.innerHTML = reader.responseText;
}
}
</script>
</head>
<body>
<div id="container">
<input type="button" value="test.txt" onclick="loadFile()" />
<div id="main">
</div>
</div>
</body>
</html>
This can be done quite easily using javascript XMLHttpRequest() class (AJAX):
function FileHelper()
{
FileHelper.readStringFromFileAtPath = function(pathOfFileToReadFrom)
{
var request = new XMLHttpRequest();
request.open("GET", pathOfFileToReadFrom, false);
request.send(null);
var returnValue = request.responseText;
return returnValue;
}
}
...
var text = FileHelper.readStringFromFileAtPath ( "mytext.txt" );
Javascript doesn't have access to the user's filesystem for security reasons. FileReader is only for files manually selected by the user.
(fiddle:
https://jsfiddle.net/ya3ya6/7hfkdnrg/2/ )
Usage
Html:
<textarea id='tbMain' ></textarea>
<a id='btnOpen' href='#' >Open</a>
Js:
document.getElementById('btnOpen').onclick = function(){
openFile(function(txt){
document.getElementById('tbMain').value = txt;
});
}
Js Helper functions
function openFile(callBack){
var element = document.createElement('input');
element.setAttribute('type', "file");
element.setAttribute('id', "btnOpenFile");
element.onchange = function(){
readText(this,callBack);
document.body.removeChild(this);
}
element.style.display = 'none';
document.body.appendChild(element);
element.click();
}
function readText(filePath,callBack) {
var reader;
if (window.File && window.FileReader && window.FileList && window.Blob) {
reader = new FileReader();
} else {
alert('The File APIs are not fully supported by your browser. Fallback required.');
return false;
}
var output = ""; //placeholder for text output
if(filePath.files && filePath.files[0]) {
reader.onload = function (e) {
output = e.target.result;
callBack(output);
};//end onload()
reader.readAsText(filePath.files[0]);
}//end if html5 filelist support
else { //this is where you could fallback to Java Applet, Flash or similar
return false;
}
return true;
}
my example
<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
</head>
<body>
<script>
function PreviewText() {
var oFReader = new FileReader();
oFReader.readAsDataURL(document.getElementById("uploadText").files[0]);
oFReader.onload = function(oFREvent) {
document.getElementById("uploadTextValue").value = oFREvent.target.result;
document.getElementById("obj").data = oFREvent.target.result;
};
};
jQuery(document).ready(function() {
$('#viewSource').click(function() {
var text = $('#uploadTextValue').val();
alert(text);
//here ajax
});
});
</script>
<object width="100%" height="400" data="" id="obj"></object>
<div>
<input type="hidden" id="uploadTextValue" name="uploadTextValue" value="" />
<input id="uploadText" style="width:120px" type="file" size="10" onchange="PreviewText();" />
</div>
Source file
</body>
</html>
This is an old question but I think in 2022 there are ES6 ways to handle this:
const $node = document.getElementById('output')
const $file = document.getElementById('file')
const processTextByLine = text => {
const arr = text.split(/\r?\n/gm)
arr.map(line => console.log(line))
}
const openFile = event => {
const input = event.target
if (!input) throw new Error('null input')
const [first] = input.files
const reader = new FileReader()
reader.onload = () => {
const text = reader.result
$node.innerText = text
processTextByLine(text)
}
reader.readAsText(first)
}
$file.onchange = openFile
<input id='file' type='file' accept='text/plain'><br>
<div id='output'>
...
</div>
If your file is encoded using UTF-8 then we can make an async call using Blob.text()
const $node = document.getElementById('output')
const $file = document.getElementById('file')
const processTextByLine = text => {
const arr = text.split(/\r?\n/gm)
arr.map(line => console.log(line))
}
const openFile = async event => {
const input = event.target
if (!input) throw new Error('null input')
const [file] = input.files
const text = await file.text()
$node.innerText = text
processTextByLine(text)
}
$file.onchange = openFile
<input id='file' type='file' accept='text/plain'><br>
<div id='output'>
...
</div>
Note:
processTextByLine() function is not needed, it just shows a case if we need to process the file line by line.

Categories

Resources