Input File multiple Validation Javacript - javascript

It is possible to validate within a multiple Input file that one of the files is of type word (.doc, .docx) and another of type PDF (.pdf)?

I have a created a working codepen that shows you a javascript code which iterates over the files uploaded with the file upload input, and checks if their file extension is in pdf, doc or docx.
Though as others have mentioned in comments, checking file format in client-side is unsafe and you should double check on the server side.
Snippet below
function testFiles(){
var fileInput = document.getElementById('upload');
// iterate over files
for (let i = 0; i < fileInput.files.length; i++) {
var filename = fileInput.files[i].name
// get file extension
var file_extension = filename.split('.').pop()
if(file_extension == "pdf"
|| file_extension == "doc"
|| file_extension == "docx"){
alert(filename + ' is a .pdf, .doc or .docx file')
}
else alert(filename + ' is not an authorized file')
}
}
<input id="upload" type="file" onchange="testFiles()" multiple>

Related

How to get full path of user's file upload?

We have an issue tracking system on our intranet where we need to add effected files to the issue, including the path of the file.
We have been using an asp.net FileUpload control and using FileUpload1.PostedFile.FileName to get the path of the file that the user selects and uploads. The files are usually not on the users local machine, but on network drives that are on a separate server than the issue tracking system. We use the upload as an easy way to add files to the issue tracker.
This does not work in any recent browsers for security reasons, only on Internet Explorer which is on its way out.
Is there any way to get this to work? At least for intranet sites? Or is there a better way to go about this? We do absolutely need the file path, and if we had to copy and paste it would make this process take much longer as it would make it a two step process and many files often need to be added.
Here is a snippet of the asp.net page:
<asp:FileUpload ID="FileUpload1" runat="server" />
And here is how I was getting the file path:
Dim sFileLocation As String = ""
Dim sFileName As String = ""
Dim sExtension As String = ""
sFileName = GetFileName(Me.FileUpload1.FileName)
sExtension = GetExtension(Me.FileUpload1.FileName)
sFileLocation = Me.FileUpload1.PostedFile.FileName
sFileLocation = sFileLocation.Replace(sFileName, "")
This is only works for IE 11, did not test IE edge.
Chrome does not work.
Due to intranet, we only allow use IE internally.
Here is the logic I am using to check the file size and name, validateFile function can get the file path without problem
<asp:FileUpload ID="fuAFS" runat="server" CssClass="cssAFS cssFu" AllowMultiple="false" Width="550px" /> <asp:Button ID="btnAFS" runat="server" Text="Upload AFS" OnClientClick="return ValidateFile('cssAFS');" />
function ValidateFile(cssName) {
var fu = $('.' + cssName);
//Empty upload control file.length == 1
if (fu.length > 0) { //Upload control exists
var pathName = fu.val();
if (pathName == '') {
alert('Missing file. Please click the Browse button to select a file with extension pdf.');
return false;
}
}
return true;
}
$('.cssFu').on('change', function (e) {
var maxFileSize = $('#<%=hdnMaxFileSize.ClientID%>').val();
if (e.target.files.length == 1) {
if (e.target.files[0] != null) {
var size = e.target.files[0].size; //IE
var fileSize = e.target.files[0].fileSize; //Firefox
var pathName = $(this).val();
var ext = pathName.substring(pathName.lastIndexOf(".") + 1, pathName.length).toLowerCase();
if (size > maxFileSize * 1024 * 1024 || fileSize > maxFileSize * 1024 * 1024) {
alert('File size exceeds limit. Maximum file size permitted is ' + maxFileSize + ' MB.');
$(this).val('');
// Prevent form Upload
e.stopPropagation();
e.preventDefault();
} else if (ext != 'pdf') {
alert('Invalid File. Please upload a File with extension: PDF');
$(this).val('');
// Prevent form Upload
e.stopPropagation();
e.preventDefault();
}
var fileName = pathName.substring(pathName.lastIndexOf("\\") + 1, pathName.length);
if (fileName != '' && fileName.length > 100) {
alert('File name length over 100 characters, please rename the file and upload again.');
$(this).val('');
// Prevent form Upload
e.stopPropagation();
e.preventDefault();
}
}
}
#rgorr - FileUpload will never give you the full path for security reasons.
Server.MapPath(FileUpload1.FileName);

Upload json/shp/kml/kmz file and convert it into geojson

I want to upload a json/shp/kml/kmz file and convert it into geojson.
HTML
<input type="file" name="uploadfile" accept=".json,.geojson,.shp,.kml,.kmz" id="file_loader" hidden>
<input type="text" id="upload_name" placeholder="Name" aria-label="Name" >
Javascript
var jsonObj;
var fileExt = upload_name.split('.').pop(); // Get file extension
var reader = new FileReader(); // Read file into text
reader.readAsText($('#file_loader')[0].files[0]);
reader.onload = function(event) {
if (fileExt == 'geojson') {
jsonObj = JSON.parse(event.target.result); // Parse text into json
} else if (fileExt == 'shp') {
// how to convert event.target.result to geojson?
} else if (fileExt == 'json') {
//
} else if (fileExt == 'kml') {
//
} else if (fileExt == 'kmz') {
//
}
}
function addToMap(){
// This function add jsonObj as a layer to Mapbox
// No problem here
}
I've tried using
https://www.npmjs.com/package/gtran
by npm install gtran and then var gtran = require('gtran'); in my javascript file, but it gives me an error:
Could not find a declaration file for module 'gtran'
gtran doesn't have a #types/gtran.
My javascript file gets processed by webpack with babel-loader. Not sure if that has anything to do with the error.
Even if I successfully include gtran, its functions need filename as argument. My data is in a string and not a file, I don't have a filename. What do I do? Do I save the string in a file and then gtran that file?
You can't use var gtran = require('gtran'); in your frontend javascript file. It is used in Node.js.
However, you can use it with the aid of an extension like Browserify. See this post for more details.

Javascript uploading duplicates

I have a bit of html with an area where a user can drag and drop files to upload. Nested within, is a "browse for files" button that clicks() a hidden file input should they choose the traditional upload method. Everything works well thus far with the exception that if a user drags and drops multiple files (more than one), it uploads each of them twice (3 dropped files uploads 6 files). It does not do this if the user uploads via the browse for files button, so I've narrowed it down to my on ondrop function and included that below. I can post additional code if the problem isn't in this code block.
Update: I logged my variable droppedfile to the console once before the for loop and once after and noticed that when logged after the for loop and 2 files were dropped, the variable contained 2 fileLists and each list contained both of the files (making 4 uploads). How is my for loop altering my variable??
dropzone.ondrop = function(e){
e.preventDefault();
this.className = 'dropzone';
var droppedfile = e.target.files || e.dataTransfer.files;
for (i=0; i < droppedfile.length; i++) {
if(droppedfile[i].type != "text/plain" && droppedfile[i].type != "application/pdf" && droppedfile[i].type != "application/msword"){
alert(droppedfile[i].type + " file types are not allowed.");
}else{
uploadButton.innerHTML = 'Uploading...';
//calls a function that assigns the file to a new formdata obj and sends via ajax
upload(droppedfile);
}
}
}
The problem occurs because you are uploading both the files each time the for loop is executed.
Replace
upload(droppedfile);
witn
upload(droppedfile[i]);
Alternatively You can ensure all files are valid before uploading
var valid=true;
for (i=0; i < droppedfile.length; i++) {
if(droppedfile[i].type != "text/plain" && droppedfile[i].type != "application/pdf" && droppedfile[i].type != "application/msword"){
alert(droppedfile[i].type + " file types are not allowed.");
valid=false;
}
}
if(valid) {
uploadButton.innerHTML = 'Uploading...';
upload(droppedfile);
}

how do I remove an item that is set to upload?

I have created an uploader using javascript and php. The problem is that I only want to allow specific file types. I have it letting the user know the file is not valid but I am not sure how to remove the file from being uploaded. Can anyone tell me how to remove the upload?
multiUploader.prototype._preview = function(data) {
this.items = data;
if (this.items.length > 0) {
var html = "";
var uId = "";
for (var i = 0; i < this.items.length; i++) {
uId = this.items[i].name._unique();
if (typeof this.items[i] != undefined) {
if (self._validate(this.items[i].type) <= 0) {
var errorClass = '<h3 class="text-danger">Invalid file format' + this.items[i].name + '</h3>'
jQuery(".errorContent").append(errorClass);
jQuery.remove(this.items[i]);
}
html += '<div class="dfiles" rel="' + uId + '"><h5>' + this.items[i].name + '</h5><div id="' + uId + '" class="progress" style="display:none;"></div></div>';
}
}
jQuery("#dragAndDropFiles").append(html);
}
}
This is not all of the code, just the function that displays my error message and also shows the uploaded file on the page. I tried it with jQuery.remove but it does not work. Any ideas are appreciated
what is a "file type"? I could send you a .php file that ends in .jpg, would you accept that? (I hope not!). Let the user upload the files with a warning that files X, Y, Z are not going to be accepted based on extension mismatch. Then actually test their content to see if the files are truly what their extension claims, because -and this part is important- your javascript in no way guarantees that what you're going to get is what you wrote your scripts to allow. Changing your script in my browser is a matter of opening my devtools and rewriting your script, then hitting ctrl-s. Now my browser will be running my code, not your code, and happily upload my files anyway.
Always, always, server-verify the user data.

How to save form input data to a XML file using Javascript?

I want to save these form inputs in a file (e.g XML) in order to be able to use it later in the form again:
<html>
<body>
<form action="demo_form.asp">
First name: <input type="text" name="FirstName" value="Mickey"><br>
Last name: <input type="text" name="LastName" value="Mouse"><br>
<input type="submit" value="Submit">
</form>
<p>Click the "Submit" button and the form-data will be sent to a page on the server called "demo_form.asp".</p>
</body>
</html>
What is the easiest way to achieve this? I can't use PHP or ASP.NET.
Unless you are using a server side language saving data to the file system (I assume you mean that by wanting to save a XML file) is not possible. A JavaScript application has no ability to write to the file system.
You can use HTML5's storage capabilities instead. And have a look at "How to save data from a form with HTML5 storage"
If you need to save the data to your server, then you will need server-side tools ASP.NET or PHP, as you say.
However, you said you wanted to store the data in XML format so that you can use it later in the form. You can use the data later in the same page and put it into XML like this:
interval=setInterval(function(){
first=$('[name*="FirstName"]').val();
last=$('[name*="LastName"]').val();
output='<data><first>'+first+'</first><last>'+last+'</last></data>';
$('#output').text(output);
},200);
http://jsfiddle.net/pA8nC/
But I can't think of any reason why you would want to do that! You can use plain JavaScript or JQuery to access the values directly:
JQuery:
firstName=$('[name*="FirstName"]').val();
lastName=$('[name*="LastName"]').val();
JS:
firstName=document.form.FirstName.value;
lastName=document.form.LastName.value;
What you are asking can only be done in server side !
From your question I could understand that you are newbie to web development and I know you just want to keep the data so that you can use it later on demand
My suggestion is just keep the values in cookie or url or hidden field as XML string you better choose hidden field.
This code example below will allow you to grab data from fields on the page and write them out to a txt file directly to the users local box. I am currently looking for a way to write them out to XMl for a project that I am on, but at the very least I can get the data I want written out to a text file.
var userInput = document.getElementById("userInputId").value;
var fileURL = 'data:application/notepad;charset=utf-8,' + encodeURIComponent(userInput);
var fileName = "test.txt";
if (!window.ActiveXObject) {
var save = document.createElement('a');
save.href = fileURL;
save.target = '_blank';
save.download = fileName || 'unknown';
var event = document.createEvent('Event');
event.initEvent('click', true, true);
save.dispatchEvent(event);
(window.URL || window.webkitURL).revokeObjectURL(save.href);
}
// for IE
else if (!!window.ActiveXObject && document.execCommand) {
var _window = window.open(fileURL, '_blank');
_window.document.close();
_window.document.execCommand('SaveAs', true, fileName || fileURL)
_window.close();
}
This javascript will trigger a file download of a form's data (for each form) when the form is submitted. It does not use XML as I do not know what your schema looks like (and I question it's usefulness whereas a form serialized string can be quickly posted using xhr).
http://jsfiddle.net/CKvcV/
(function () {
var makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
return window.URL.createObjectURL(data);
},
serializeForm = function(form, evt){
var evt = evt || window.event;
evt.target = evt.target || evt.srcElement || null;
var field, query='';
if(typeof form == 'object' && form.nodeName == "FORM"){
for(i=form.elements.length-1; i>=0; i--){
field = form.elements[i];
if(field.name && field.type != 'file' && field.type != 'reset'){
if(field.type == 'select-multiple'){
for(j=form.elements[i].options.length-1; j>=0; j--){
if(field.options[j].selected){
query += '&' + field.name + "=" + encodeURIComponent(field.options[j].value).replace(/%20/g,'+');
}
}
}
else{
if((field.type != 'submit' && field.type != 'button') || evt.target == field){
if((field.type != 'checkbox' && field.type != 'radio') || field.checked){
query += '&' + field.name + "=" + encodeURIComponent(field.value).replace(/%20/g,'+');
}
}
}
}
}
}
return query.substr(1);
}
, _onsubmit = function() {
var _href = makeTextFile(serializeForm(this));
var _a = document.createElement("A");
_a.setAttribute('download', 'export.txt');
_a.setAttribute('target', '_blank');
_a.href = _href;
_a.click();
window.URL.revokeObjectURL(_href);
//return false;
};
[].forEach.call(
document.querySelectorAll('form'),
function(f) { f.onsubmit = _onsubmit; }
);
})();
Build this into a bookmarklet or whatever. But if you are looking to save yourself some typing you might want to store the value in localStorage instead of a file. You do not mention how you intent to reuse the data and it would be much easier to pull it from localStorage than to build a dynamic file uploader and make the user find the correct file.

Categories

Resources