Input file validation with knockout JS and file API - javascript

I am new to knockout js and trying to write custom validation for file input from client side using knockout JS and file API. The main aim is to validate the file extension and file size, and clear the file input path should validation error occur.
Below is the code being done using pure javascript. Appreciate if someone could lend a hand.
function FileAPIViewModel() {
var self = this;
}
ko.applyBindings(new FileAPIViewModel());
$('#i_file').change( function() {
//check whether browser fully supports all File API
if (window.File && window.FileReader && window.FileList && window.Blob)
{
//get the file size and file type from file input field
var fsize = $('#i_file')[0].files[0].size;
var ftype = $('#i_file')[0].files[0].type;
if(fsize>10)
{
alert(fsize +" bites\nToo big!");
$('#i_file').val('');
}
switch(ftype)
{
case 'image/png':
case 'image/gif':
break;
default:
alert('Unsupported File!');
$('#i_file').val('');
}
}else{
alert("Please upgrade your browser, because your current browser lacks some new features we need!");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.min.js"></script>
<input type="file" input="" id="i_file" />
<input type="button" value="Submit" id="i_submit" />

You could try making a custom jquery validator for this.
$.validator.addMethod("filesize", function (value, element, params) {
//20000000
var ext = value.substr(value.length - 4);
//If there is no file
if (value === "") {
return false;
}
//check extension
if (ext !== null) {
if (ext !== ".pdf") {
return false;
}
}
//check file size
if(element.files[0] != null){
if (element.files[0].size > 20000000) {
return false;
}
}
return true;
}, 'Must Upload A Valid PDF Under 20MB');
Then add rule to your input(s) which I believe is i_file
$('[id^="i_file"]').each(function () {
$(this).rules('add', {
filesize: true
});
});

Related

JAVASCRIPT - Read local file, filter for a word and print word's line

I have the following code. It can open a file and display it in the browser. But I want to:
- Select many files instead of one;
- Then Filter on these files for a word (username);
- Then print username's line (text file: username xxxx);
- If the word "username" is not found , print - text file: not found
Any idea?
<!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>
I havent tested this, but does the basic idea work? Read the files through a for-loop, and search for your target string. If you get to the end and you dont find it, return your empty message;
function SearchFiles(var target_string, var file_paths){
var fs = require("fs");
my_file_paths.foreach(function(filepath){
var text = fs.readFileSync(filepath);
var pos = text.search(target_string);
if (pos>1) {
return text.substring(pos, pos + target_string.length);
}
}
return "not found"
}
// now to use the function
var my_file_paths; // init this to what you want to search through
var target_username; // init this as well
var found_username = SearchFiles(target_username, my_file_paths);
DisplayContents("text file: " + found_username);

upload csv and save it to a local folder Jquery

What I would like to have happen is a when a user uploads a CSV from an HTML page that file should save to a local directory that I have provided.
One of two things should happen, if the file already exists it should overwrite, otherwise it should create a new file.
Here is the code that I have:
<!DOCTYPE html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// The event listener for the file upload
document.getElementById('txtFileUpload').addEventListener('change', upload, false);
// Method that checks that the browser supports the HTML5 File API
function browserSupportFileUpload() {
var isCompatible = false;
if (window.File && window.FileReader && window.FileList && window.Blob) {
isCompatible = true;
}
return isCompatible;
}
// Method that reads and processes the selected file
function upload(evt) {
if (!browserSupportFileUpload()) {
alert('The File APIs are not fully supported in this browser!');
} else {
var data = null;
var file = evt.target.files[0];
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function(event) {
var csvData = event.target.result;
data = $.csv.toArrays(csvData);
if (data && data.length > 0) {
alert('Imported -' + data.length + '- rows successfully!');
} else {
alert('No data to import!');
}
};
reader.onerror = function() {
alert('Unable to read ' + file.fileName);
};
}
}
});
</script>
</head>
<body>
<div id="dvImportSegments" class="fileupload ">
<fieldset>
<legend>Upload your CSV File</legend>
<input type="file" name="File Upload" id="txtFileUpload" accept=".csv" />
</fieldset>
</div>
<script>
document.getElementById("data").innerHTML;
</script>
</body>
</html>
You need a server (PHP or NodeJS) that exposes this html file ( usually placed in a public folder ) and then serve this html file, you can then do the validation and the storage through the server. You could later on add a database hook, but that depends on your needs and probably the amount of data you'll be uploading.

zip.js to read file name inside zip . (Client side scripting only)

have multiple file inputs in form now I have to check for each file input that zip file doesn't contain any invalid files (doc, docx and pdf only allow).
I wrote
<script src="https://code.jquery.com/jquery-2.2.1.js" integrity="sha256-eNcUzO3jsv0XlJLveFEkbB8bA7/CroNpNVk3XpmnwHc=" crossorigin="anonymous"></script>
<script type="text/javascript" src="/js/zip.js"/>
<script type="text/javascript" src="/js/inflate.js"/>
<script type="text/javascript" src="/js/deflate.js"/>
<script type="text/javascript" src="/js/z-worker.js"/>
<script type="text/javascript">
$(document).ready(function () {
if((window.location.href.indexOf("LibraryItemUpload`1&ParentId=7d428470-2234-41c0-85f4-a512d51198c6") > -1) || (window.location.href.indexOf("LibraryItemUpload%601&ParentId=7d428470-2234-41c0-85f4-a512d51198c6") > -1))
{
$("input:file").change(function () {
var regex=new RegExp("^[A-Za-z0-9 ]+$");
var file=this.files[0];
var key = this.value;
var ze = key.split('\\').pop();
var filename = ze.split('.')[0];
var extension=key.split('.').pop().trim().toLowerCase();
if(extension == 'zip')
{
zip.createReader(new zip.BlobReader(file), function(reader) {
// get all entries from the zip
reader.getEntries(function(entries) {
if (entries.length) {
// get first entry content as text
entries[0].getData(new zip.TextWriter(), function(text) {
// text contains the entry data as a String
console.log(text);
// close the zip reader
reader.close(function() {
// onclose callback
});
}, function(current, total) {
// onprogress callback
});
}
});
}, function(error) {
});
}
if (!regex.test(filename)) {
alert('Please do not use special characters in file name please rename file name and upload it again.');
location.reload();
}
else {
return true;
}
});
}
});
</script>
and written code to read file name from zip.js but flow doen't go in zip.createReader function.
please suggest me if another javascript available for read zip file, I just want entries object to read files name.
function readEntries(entries) {
var entryLength = entries.length;
for (i = 0; i < entryLength; i++) {
var entry = entries[i];
var fileName = entry.filename.substring(entry.filename.lastIndexOf("/") + 1); //if inside folder
var ext = fileName.split(".").pop().toLowerCase();
if (ext.toUpperCase() == 'DOC' || ext.toUpperCase() == 'PDF' ||
ext.toUpperCase() == 'DOCX') {
//logic
}
}
}
zip.useWebWorkers = false;//explicitly include (required) zip-workers ['zip.js','zip-fs.js','z-worker.js','inflate.js','deflate.js']
var fileInput = document.getElementById("zipfile");//Input File
fileInput.addEventListener('change', function(event) {
zip.createReader(new zip.BlobReader(fileInput.files[0]), function(zipReader) {
zipReader.getEntries(readEntries);
}, function (error) {
console.log(error);
});
});
I have not tested this piece of code, but I have used similar logic before.

how to correct this javascript?

could you please help me to allow the asyncFileUploader to use these extensions:(rar,pdf,doc,docx,zip)...
im not an jscript expert, so i have been tying to edit the script by my self but i failed ...
var fileExtension = args.get_fileName();
if (fileExtension.indexOf('.doc') != -1) {
$get("dvFileErrorInfo").style.display = 'block';
$get("<%=lblError.ClientID%>").innerHTML = "File extension [.doc] not supported";
$get("dvFileInfo").style.display = 'none';
return;
}
Change the condition to fileExtension.indexOf('.doc') == -1 && fileExtension.indexOf('.pdf') == -1 && etc so on. Copy paste the condition and add the extensions you wanna allow. This would mean that any extensions not in the conditions will fullfil the condition and the message will display
You can use the OnClientUploadStart property on the control to fire a JavaScript function for validation, like this:
<cc1:AsyncFileUpload ID="FileUpload" runat="server"
OnClientUploadStarted="AssemblyFileUpload_Started" />
Then use this script on your page:
<script>
function AssemblyFileUpload_Started(sender, args) {
var filename = args.get_fileName();
var ext = filename.substring(filename.lastIndexOf(".") + 1);
if (ext != 'zip') {
throw {
name: "Invalid File Type",
level: "Error",
message: "Invalid File Type (Only .zip)",
htmlMessage: "Invalid File Type (Only .zip)"
}
return false;
}
return true;
}
</script>
Use other file types as well.

Undefined Function for Imported Library in JavaScript

I'm parsing a CSV file into arrays and using jquery.csv to do the grunt work. My script reads:
<script>
$(document).ready(function() {
// The event listener for the file upload
document.getElementById('txtFileUpload').addEventListener('change', upload, false);
// Method that checks that the browser supports the HTML5 File API
function browserSupportFileUpload() {
var isCompatible = false;
if (window.File && window.FileReader && window.FileList && window.Blob) {
isCompatible = true;
}
return isCompatible;
}
// Method that reads and processes the selected file
function upload(evt) {
if (!browserSupportFileUpload()) {
alert('The File APIs are not fully supported in this browser!');
} else {
var data = null;
var file = evt.target.files[0];
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function(event) {
var csvData = event.target.result;
data = $.csv.toArrays(csvData);
if (data && data.length > 0) {
alert('Imported -' + data.length + '- rows successfully!');
} else {
alert('No data to import!');
}
};
reader.onerror = function() {
alert('Unable to read ' + file.fileName);
};
}
}
});
My console reads that there is an "Uncaught TypeError: Cannot read property 'toArrays' of undefined". Also in the head section, I imported the library using <script src="jquery.csv-0.71.js"></script>, the JS file residing in the same folder. Any ideas why this error is occurring? Have I imported the library incorrectly, do I need to initialize something? Thanks!
Make sure you're importing jquery.csv-0.71.js after importing jQuery and that your script is running after both.
<script src="jquery.js"></script>
<script src="jquery-csv.js"></script>
<script>/* Your script */</script>

Categories

Resources