How to upload a csv file multiple times on Safari using Angularjs? - javascript

I have written a web app where I want to upload a CSV file. It is working as intended on Chrome, but it does not work on Safari.
Below is the Angularjs code to upload file,
$scope.uploadFile = function (file) {
var name, extension, browser;
var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);
if (isSafari) {
name = file.fileName;
extension = name.split('.')[name.split('.').length - 1].toLowerCase();
if (extension != "csv") {
alert("Selected File is not a valid .CSV file. Please select a .CSV file.");
return false;
}
}
//Code to save file to server
}
Below is the HTML code to call the above function,
<input id="uploader" type="file" ngf-select="uploadFile(uploadedFile)"
ng-model="uploadedFile" ngf-max-size="100MB" name="file"
ngf-accept="'application/csv, text/csv, text/comma-separated-values, *.csv, .csv, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel'">
When I click the input button the first time, the function gets called correctly. The selected file gets uploaded as expected. The issue begins when I try to upload the same file the second time. The uploadFile function gets called as soon as I click the <input > file picker.
The above problem described occurs only in Safari, and not in Chrome.
How do I modify my code such a way that every time I click to upload a file, the function gets called only after I select the file?
Thank you for reading my question.

Related

<a> element does not recognize the file extension automatically when downloading a file

I'm currently developing an application where the user clicks on an element, that element calls a JS function and the function handles a file download.
The files are reports generated dynamically by Devexpress XtraReports module, converted to Base64 and then sent back to the client side. When the client receives the Base64 string, the JS function creates an <a> element, sets the href attribute to data:application/pdf;base64,JVBERi0xLjQNCiWio[...] and simulates a click with the click() event.
Here's the piece of JS code that handles the file download:
let downloadLink;
try {
downloadLink = executionId ? await getLinkPdfBase64(executionId) : false;
} catch (error) {
downloadLink = false;
console.log(error);
}
if (downloadLink) {
const aElement = document.createElement("a");
downloadLink = "data:application/pdf;base64," + downloadLink;
aElement.setAttribute("download", currentReportData.LayoutName);
aElement.setAttribute("href", downloadLink);
aElement.click();
aElement.remove();
} else {
DevExpress.ui.dialog.alert( //Ignore this, it's a Devexpress component
"Your report could not be generated",
"Alert"
);
}
The problem is:
When I generate a report with custom parameter types, Devexpress generates it correctly (the Base64, if converted to string, is visibly correctly formed) but the browser (Google Chrome) downloads the file with the extension ".0".
If the report has normal Devexpress parameters (like Strings, Int32, Guids, etc)) the file is downloaded with the correct ".pdf" extension.
Here's a picture of a correctly downloaded PDF and a ".0" extension file:
Could it be the JS function the cause or the solution to the problem? If not, almost for sure there will be something wrong with the report generator (Devexpress).
NB: If I manually change the ".0" extension to ".pdf" the file opens and it is displayed / formed correctly.
Turns out I ended up solving it just by adding the file extension ".pdf" in the download attribute, so when the browser can't recognize it, you are already specifying which one it is:
aElement.setAttribute("download", currentReportData.LayoutName + ".pdf");

Does html input support drag & drop from zip folder?

I implemented a drag & drop functionality in a React component with a HTML input box. It works perfectly, it receives the file and uploads it to Amazon S3, checking if the file type is compatible with the one specified from props.
The problem occurs when dragging a file from a ZIP file. I console.loggued the resultant file object, and the only difference with a file dragged from a desktop folder is the size (From ZIP file => size = 0).
When I'm dragging the file, is there a way to recognize that it comes from a ZIP file so it waits until the file has finished uploading to the input? Also, how could I check if the file has finished uploading?
The function that receives the file and checks it:
export default function(e, onUpload, acceptedTypes) {
e.stopPropagation()
e.preventDefault()
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
const file = e.dataTransfer.files[0]
if (isAcceptedType(file, acceptedTypes)) {
onUpload(file)
}
}
}
I forgot to mention initially, that when I drop a file in the input, it gets "uploaded" to S3 immediately, but with size 0 (Since it comes from a ZIP file), so the site recognizes it as a file, but when I'm trying to see the content it says error.
Thank you!
I ended up with this workaround, as I also haven't found an actual solution:
// when dropped from a zip only one file gets recognized
if(droppedFiles.length === 1) {
const timeTolerance = 10;
const now = new Date().getTime();
const isAutoGenerated = now - file.lastModified < timeTolerance;
if (file.size === 0 && isAutoGenerated) {
return false; // invalid file
}
}
Because the lastModified is so close to the current time it's most likely automatically generated and in combination with the size of 0 I identify it as an placeholder file.

ASP.NET - Validate Excel File Content

I have a page with a file input where the user is supposed to upload an excel file to insert a large amount of records to a specific table. I found this Javascript code to help validate if the inserted file has one of the requested Excel extensions:
var hash = {
'xls': 1,
'xlsx': 1,
};
function checkExtension() {
var filename = $("#uploadFile").val();
var re = /\..+$/;
var ext = filename.slice(filename.lastIndexOf(".") + 1).toLowerCase();
if (hash[ext]) {
return true;
} else {
alert("Invalid file type. Please insert a valid Excel file.");
event.preventDefault();
return false;
}
}
However, as efficient as this code is at validating the file's extension, it won't validate the file's content allowing someone to upload a file with different type of content but it's extension renamed to ".xls" or ".xlsx". How can i get around this scenario?
You can Properly Validate Your Excel File in 3 steps
In Asp.net FileUploader Control has an Attribute Called 'accept' <asp:FileUploader accept='.xls,.xlsx'/>. It will by default let the user to select only xls and xlsx extension file. However still user can choose All file options to upload another file.
Verify if the Extension of the Filename contains .xls from Javascript as well as Code Behind.
Use Aspose.Cells dll and try to fetch the xls file it will return Exception 'InvalidFileFormatException' if the File is not xls or xlsx.

select a file without browsing using javascript

My main program prompts the user to browse for a file in order to convert it using ffmpeg. This is the format of the file browsing:
<div>
<p class="lead">1. Select audio file for conversion ( mp3, wma):</p>
<div class="quick-center">
<div class="quick-drop-outer quick-left"><input id="inFile" type="file" id="inputFile"/></div>
</div>
</div>
and this is the code where to launch the file and convert it according to selection: not whole code supported because no need of file conversion:
document.getElementById('inFile').addEventListener('change', handleFileSelect, false);
function readInputFile(file) {
// disable conversion for the time of file loading
$('#convert').attr('disabled', 'true');
// load file content
var reader = new FileReader();
reader.onload = function(e) {
$('#convert').removeAttr('disabled');
fileName = file.name;
fileBuffer = e.target.result;
}
reader.readAsArrayBuffer(file);
}
function handleFileSelect(event) {
var files = event.target.files; // FileList object
// files is a FileList of File objects. display first file name
file = files[0];
console.log(file);
if (file) {
$("#drop").text("Drop file here");
readInputFile(file);
}
}
now, here is my problem, what I want to do is to upload the file directly from a selected folder (upload) where the audio files are already there. I want instead of browsing for the file, I want the last file in the upload folder to be uploaded instead of "inFile" so that conversion can happen.
how could that happen.
edit: A small brief about my project. the user records his voice using HTML5 and the link of that audio is uploaded using ajax and php into a folder named upload.what I simply want is instead of browsing that file, I want to write down the path of the file in the selected folder automatically once recording is done for conversion.so, instead of dropping the file by user, the file would be dropped and conversion starts from there.
help please.Thank you in advance
From JavaScript You dont have access to files and directories on host system.
Why?
Because is VERY IMPORTANT SECURITY feature to block reading Your disc for files from scripts.

Grab SINGLE file from input type=file in IE

I understand IE9 and below don't support file uploads for inputs with multiple files.
But I'm unable to even grab the file in a single file upload!
HTML:
<input type='file' id='imgfile' />
Javascript:
var input = document.getElementById("imgfile");
input.addEventListener("change", function (evt) {
file = this.files[0]; /** Is it possible to even just do this much in IE? **/
if (!!file.type.match(/image.*/)) {
if ( window.FileReader ) {
reader = new FileReader();
reader.onloadend = function (e) {
showUploadedItem(e.target.result, file.fileName);
};
reader.readAsDataURL(file);
}
if (formdata) {
formdata.append("images[]", file);
}
}
/* some stuf */
}
I know the FileReader API won't work in IE, then what will? There must be some solution. I've spent a while on this but it's eluding me!
Edit
I should have mentioned, I'm using ajax. So this javascript above is trigger after the uploaded file is uploaded using PHP. Does this mean that we can't even use ajax in IE?
input.files is an HTML5 property and it most likely not supported in whatever browser you're testing this with.
Have you tried input.value?
You can't upload a selected file with javascript using IE. To send this file to the server, you'll need to submit your form with the file upload in it (the good old way).
Recents browsers support Ajax file upload (Chrome, Firefox and Opera). For this, you will need XHR2. IE9 doesn't support it, but IE10 should : http://caniuse.com/#feat=xhr2
But I don't understand how your javascript is suppose to take the file back from the server. If you want to use Ajax, you are suppose to read the file from your Ajax request output, not from your fileupload component.

Categories