In the code snippet below, I would like to get rid of the 'Upload' button and wanna invoke this 'Upload()' inside 'incomingfile()' function. Is there a way to invoke the "Upload()" function without clicking the button?
<input type="file" id="file-upload" (change)="incomingfile($event)"/>
<label for="file-upload">Upload file</label>
<button type="button" class="btn btn-info" (click)="Upload()">Upload</button>
incomingfile(event) {
this.file = event.target.files[0]
}
Upload() {
let fileReader = new FileReader()
fileReader.onload = e => {
this.arrayBuffer = fileReader.result
var data = new Uint8Array(this.arrayBuffer)
var arr = new Array()
for (var i = 0; i != data.length; ++i)
arr[i] = String.fromCharCode(data[i])
var bstr = arr.join('')
var workbook = XLSX.read(bstr, { type: 'binary' })
var first_sheet_name = workbook.SheetNames[0]
var worksheet = workbook.Sheets[first_sheet_name]
this.fileData = XLSX.utils.sheet_to_json(worksheet, { raw: false })
console.log(this.fileData)
}
fileReader.readAsArrayBuffer(this.file)
}
You will have to trigger the DOM Button element in the function incomingfile:
const el = document.getElementsByTagName('button');
el.click();
Unless I'm missing something from your description, think you just need to call Upload() function instead of having a user event trigger it, so just add it to your other function:
incomingfile(event) {
this.file = event.target.files[0];
Upload();
}
Why don't u call like below code
incomingfile(event) {
this.file = event.target.files[0];
this.Upload();
}
Yes called upload method into incomingFile method like shown below.
incomingfile(event) {
this.file = event.target.files[0]
upload();
}
thanks
Related
In my app, I have an Upload button that enables the user to search files and upload them. I also defined a textarea and I want the user to be able to paste the file that he copied and upload it that way (like you would do in an e-mail or whatsapp etc.). Right now, when I try to paste the file that I've copied, nothing happens and the file doesn't paste. My code is below. What should I do to upload files by paste?
HTML:
<div>
<button mat-stroked-button class="primary-fg" (click)="onFileUploadClick($event)">
<mat-icon>attach_file</mat-icon>
Upload
</button>
<mat-form-field appearance="fill">
<mat-label>Paste</mat-label>
<textarea matInput
cdkTextareaAutosize
#autosize="cdkTextareaAutosize"
cdkAutosizeMinRows="1"
cdkAutosizeMaxRows="5"
id="pasteArea"></textarea>
</mat-form-field>
<script>
window.addEventListener("paste", e => {
if (e.clipboardData.files.length > 0) {
const fileInput = document.querySelector("#fileInput");
fileInput.files = e.clipboardData.files;
}
});
</script>
</div>
<input hidden type="file" id="fileInput" #fileInput multiple />
TS:
onFileUploadClick(event: any) {
event.preventDefault();
const fileInput = document.getElementById('fileInput') as HTMLInputElement;
fileInput.value = '';
fileInput.onchange = () => {
let tempFiles: IAttachment[] = [];
for (let index = 0; index < fileInput.files.length; index++) {
const file = fileInput.files[index];
const fileSize = file.size / 1024 / 1024; // in MB
if (fileSize <= 5) {
tempFiles.push({ FileInfo: file });
}
else {
this._dialog.open(FuseSimpleDialogComponent, {
width: "400px",
data: {
title: "Uyarı",
message: "Dosya boyutu 5MB'den büyük olduğundan seçilemez. Dosya Adı: " + file.name
}
});
}
}
tempFiles.forEach(f => this.uploadFile(f));
};
fileInput.click();
}
/**
*
* #param file
*/
private uploadFile(file: IAttachment) {
if (file.FileData) return; //file already uploaded
let fileReader: FileReader = new FileReader();
let $that = this;
let data: any;
fileReader.onerror = function (): void {
//show error message
};
fileReader.onloadend = function (): void {
if (FileReader.prototype.readAsBinaryString) {
data = btoa(fileReader.result as string);
}
else { //support for IE
data = ($that as any).arrayBufferToBase64(fileReader.result);
}
file.Name = file.FileInfo.name;
file.FileData = data;
file.CreateDate = new Date();
file.CreateUser = $that.user;
let allFiles = $that.Attachments ? $that.Attachments.slice(0) : [];
allFiles.unshift(file);
$that.Attachments = allFiles;
$that.AttachmentsChange.emit(allFiles);
};
if (FileReader.prototype.readAsBinaryString) {
fileReader.readAsBinaryString(file.FileInfo);
}
else { //support for IE
fileReader.readAsArrayBuffer(file.FileInfo);
}
}
Careful with you approach, simply pasting a file into a textarea will do nothing as a text area is made to receive... text.
You need to have an input file somewhere on your component and an event listener on window for the paste event.
Then take the paste event and try to see if it includes a file, if yes, start the uploading process, if not, paste the text in the textarea.
This is how I would approach it.
This question already has answers here:
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 3 years ago.
I have a problem with a file reader, it load the file never the fist time, and it's like a queue. I mean: it start from the second time I select a file but it upload the first.
Can I solve this?
Here the code.
<v-text-field
v-if="switch1"
label="Upload Fattura"
#click='onPickFile'
v-model='fatturaFileName'
prepend-icon="mdi-paperclip"
></v-text-field>
<input
type="file"
style="display: none"
ref="fileInput"
accept="text/xml"
#change="onFilePicked"
>
onPickFile () {
this.$refs.fileInput.click();
}`
onFilePicked (event) {
if (event) event.preventDefault();
var files = event.target.files[0];
if (files !== undefined) {
this.fatturaFileName = files.name;
// If valid, continue
const fr = new FileReader();
fr.readAsText(files);
fr.addEventListener('load', () => {
this.fatturaUpload = fr.result;
});
} else {
this.fatturaFileName = ''
this.fatturaFileObject = null
}
console.log(this.fatturaUpload);
}
It works fine using the following code :
onFilePicked (event) {
if (event) event.preventDefault();
var fichier = event.target.files[0];
if (fichier != undefined) {
const fr = new FileReader();
fr.readAsDataURL(fichier);
var reader = new FileReader();
let file = fichier;
reader.readAsText(file, "UTF-8");
reader.onload = evt => {
console.log("1",evt.target.result)
};
} else {
console.log("2",fichier)
this.fatturaFileName = ''
this.fatturaFileObject = null
}
console.log("3",this.fatturaUpload);
this.fatturaFileName = '';
this.fatturaFileObject = null;
}
See the Pen
Vuetify Template by boussadjra (#boussadjra)
on CodePen.
With the following input field, the user submits one or multiple HTML files.
<input type="file" id="inputfield" accept="text/html" multiple/>
<div id="get-files">Get Files</div>
When get-files is clicked, how can I get the content of each file on the input field and mess with each file content using the fileReader API?
I tried the following but receive no errors or content.
$("#get-files").on("click", function() { getFilesContent(); });
function getFilesContent() {
var pages = $("#inputfield")[0].files;
// get files data
for (var i = 0; i < pages.length; i++) {
var reader = new FileReader();
reader.onload = (function() {
return function(e) {
console.log($("#inputfield")[0].result);
}
});
reader.readAsText(pages[i]);
}
}
Try this instead
function getFilesContent() {
var pages = $("#inputfield")[0].files;
for (let i = 0; i < pages.length; i++) {
let reader = new FileReader();
reader.onload = function() {
console.log(reader.result);
}
reader.readAsText(pages[i]);
}
}
reader.result contains your HTML data.
I want to change name's file selected by input type=file, but it doesn't work.
This is my code:
$("document").ready(function() {
$('body').on('change', '#FileID', function() {
var name = document.getElementById('FileID');
name.files.item(0).name = Math.floor(Math.random() * 100000);
console.log('Selected file: ' + name.files.item(0).name);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id='FileID' class='class1' type='file' name='Images' value='' />
To change the name of a File object, you need to create a new File instance.
You can create one from a previous File object and it will act a simple wrapper over the data on disk.
The sketchier part is to update the <input type="file"> value to use this new File.
It is now possible through an hack as exposed in this answer of mine:
$('body').on('change', '#FileID', function(evt) {
const newName = Math.floor(Math.random() * 100000);
const input = evt.currentTarget;
const previousFile = input.files[0];
const newFile = new File([previousFile], newName);
// hack to update the selected file
const dT = new DataTransfer();
dT.items.add(newFile);
input.files = dT.files;
console.log('Selected file: ' + input.files.item(0).name);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id='FileID' class='class1' type='file' name='Images' value='' />
However since this part is still mainly an hack, I can't really recommend its use.
So if you don't need to show the updated value in the native input, don't do it. Simply update a custom UI, and use a FormData to upload to your server. The last param of FormData#append(blob, fieldname, filename) will set the filename sent by the browser in the form-data request:
const form = new FormData();
const file = new File(["some data"], "originalname.txt");
form.append("fileField", file, Math.floor(Math.random() * 100000));
console.log("original file's name: ", file.name);
new Response(form).text()
.then((content) => console.log("formdata content: ", content));
So you should not need the aforementioned hacks at all.
For anyone ending here trying to get rid of the file's name, try converting it to base64. this way it won't have the name attached to it and you could upload it how you want. I will leave a code example using reactJS for this.
1: Here is the input file type calling the onChange event with our function:
<input onChange={this.handleBackgroundImagePreview} type="file" accept="image/png,image/gif,image/jpeg"></input>
2: Then convert that image to base64
handleBackgroundImagePreview = (e) =>{
// Retrieves the selected Image or file
const file = e.target.files[0]
//Calling async file reader with a callback
let fileBase64 = '';
this.getBase64(file, (result) => {
fileBase64 = result;
console.log(fileBase64)
//In here you could upload to the server the base 64 data as you want
});
}
getBase64(file, cb) {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
cb(reader.result)
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
I'm working on a simple script for my site to upload images. I have a multiple file input <input type = 'file' name = 'files[]' id = 'hiddenFile' multiple> that is being triggered by a div click. When I queue the files, I want to be able to delete one. I know I can loop through the $('#hiddenFile').val() and splice to get the name out but I'm having an issue with figuring out the file name. When I assign the file to a new img container, how do I get the name? I've tried console.log(f.name) and a few variations but it returns an undefined error. Here are my scripts. I think I'm pretty close but this is something I'm learning as I go. Thanks!
function readURL(input) {
var files = $('#hiddenFile')[0].files; //where files would be the id of your multi file input
//or use document.getElementById('files').files;
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = function (e) {
console.log(f.name); //how can I get the
//file name here to add it to the image as an attribute?
$("<img src = '"+e.target.result+"' class = 'addedImg'>").appendTo("#imgBox");
};
reader.readAsDataURL(f);
}
}
$(document).ready(function(){
$(document).on('click', '#addBtn', function(e){
e.preventDefault();
$('#hiddenFile').click();
});
});
Try using change event , defining f within an IIFE , setting title attribute value to f.name
$(document).ready(function() {
$(document).on('click', '#addBtn', function(e) {
e.preventDefault();
$('#hiddenFile').click();
});
$("#hiddenFile").change(function(event) {
var files = this.files;
var i = 0,
len = files.length;
(function readFile(n) {
var reader = new FileReader();
var f = files[n];
reader.onload = function(e) {
console.log(f.name);
$("<img src=" + e.target.result + " class=addedImg title=" + f.name + ">")
.appendTo("#imgBox");
// if `n` is less than `len` ,
// call `readFile` with incremented `n` as parameter
if (n < len -1) readFile(++n)
};
reader.readAsDataURL(f); // `f` : current `File` object
}(i)); // `i` : `n` within immediately invoked function expression
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="addBtn">click</div>
<input type="file" style="display:none" id="hiddenFile" multiple />
<div id="imgBox"></div>
The FileReader object itself does not have access to the file name. You get the file name while you're iterating over the files list as you are doing in your for loop.
var reader = new FileReader();
reader.onload = function (e) {
//update image src or something
};
for (var i = 0, f; f = files[i]; i++) {
reader.readAsDataURL(f); //updates image src or something
//additional method to do something with file name goes here
}
And if you really want to have one method that does those two things in the for loop, then you can wrap it all up in a closure like #ebidel does in his answer here - Get filename after filereader asynchronously loaded a file#answer-12547471.