JQuery - get all fileNames inside input='file' - javascript

I have <input type="file" id="basicUploadFile" multiple="multiple"> and I want to get all file names inside this input. I've seen some example, but it gets only name of first file.
$ ('#basicUploadFile').live ('change', function () {
alert($ ('#basicUploadFile').val());
});
How can I do this? Thanks.

var files = $('#basicUploadFile').prop("files")
files will be a FileList object.
var names = $.map(files, function(val) { return val.name; });
Now names is an array of strings (file names)
FileAPI reference
files property reference

jsFiddle Demo
You can still access the files as a FileList collection without the need for over-using jQuery. I've created a quick jsFiddle demonstrating how to get the information out of the input using the FileList and File objects. Here is a snippet:
$('#basicUploadFile').live('change', function ()
{
for (var i = 0; i < this.files.length; i++)
{
alert(this.files[i].name);
alert(this.files.item(i).name); // alternatively
}
});

I used this to show in console all files name:
var input_file = $("#input_file");
input_file.on("change", function () {
var files = input_file.prop("files")
var names = $.map(files, function (val) { return val.name; });
$.each(names, function (i, name) {
console.log(name);
});
});

<input name="selectAttachment" id="selectAttachment" type="file" multiple="multiple">
<button class="btn btn-default" onclick="uploadAttachment()" type="submit">Upload</button>
function uploadAttachment() {
debugger;
var files = $('#selectAttachment').prop('files');
var names = $.map(files, function (val) { return val.name; });
}

you can extend the prototype of File Object (for example File.prototype.toJSON), and you can access the FileList of <input ..>:
<input id="myFile" type="file">
var file = document.getElementById('fileItem').files[0];
For more information check this documentation:
https://developer.mozilla.org/en-US/docs/Web/API/FileList#Using_the_file_list
check this simple example:
File.prototype.toJSON = function() {
return {
'lastModified' : this.lastModified,
'lastModifiedDate' : this.lastModifiedDate,
'name' : this.name,
'size' : this.size,
'type' : this.type
};
}
function getFiles() {
var files = document.getElementById('myFiles').files;
document.getElementById('result').innerHTML = '<h1>result</h1>'
+ JSON.stringify(files);
}
<input id="myFiles" type="file" multiple onchange="getFiles()" />
<pre id='result'></pre>
Good Luck!

Related

how to invoke a click event without clicking?

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

Facing issue to add property to object JS

I am trying to add property to file object. I am adding property like this (I am using Vue):
<input type="file" id="fileUpload" name="file" #change="setToUploadStatus" multiple>
setToUploadStatus method:
setToUploadStatus (event) {
let files = event.target.files
Array.from(files).forEach((file) => {
let id = this.randomString(10)
file.id = id
this.uploadStatus.push({
id: id,
name: file.name,
uploading: false,
uploaded: false
})
}
this.uploadFile(files)
}
uploadFile method:
async uploadFile (files) {
for (const file of files) {
// Upload file with axios
}
}
randomString method:
randomString (length) {
let text = ''
let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length))
}
return text
}
My problem is it's not adding id property always. Sometime it's adding sometime not. Specially when many files are selected. Here is a log https://prnt.sc/kxsqhi
What am I doing wrong? Please help!
Converted to a snippet here:
setToUploadStatus(event) {
let files = event.target.files
Array.from(files).forEach((file) => {
let id = this.randomString(10)
file.id = id
this.uploadStatus.push({
id: id,
name: file.name,
uploading: false,
uploaded: false
})
}
this.uploadFile(files)
}
async uploadFile(files) {
for (const file of files) {
// Upload file with axios
}
}
randomString(length) {
let text = ''
let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length))
}
return text
}
<input type="file" id="fileUpload" name="file" #change="setToUploadStatus" multiple>
First, from the code you've given there is nothing wrong with it. Perhaps the issue is coming from somewhere else.
Second, I see you want to give a unique id to every file. Generating a random string is fine, but there is still a possibility that two random strings will be the same. So here is a simple way to go about that.
new Vue({
el: "#app",
data: {},
methods: {
updateFile(event) {
let files = event.target.files
let uid = 0;
Array.from(files).forEach(file => {
file.id = ++uid;
console.log(file);
});
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<input type="file" multiple #input="updateFile" />
</div>
This implementation is simple.
Here is the JSFiddle Link: https://jsfiddle.net/clintonyeb/3qreb1L9/

Change name File selected by input type file

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);
};
}

How to change filename in a file input with AngularJS?

Is there any way to change choosen file name?
For example, I choose a file name img1. On choosing the file it have to change to dynamicname. Is there any way to change name?
<input type="file" fd-input/>
Here is a way to change a filename inside a directive:
app.directive('file', function() {
return {
scope: {
file: '='
},
link: function(scope, el, attrs) {
el.bind('change', function(event) {
var files = event.target.files;
var file = files[0];
scope.file = 'New file name';
scope.$apply();
});
}
};
});
Use it as following:
<input type="file" file="param.file" />
JSFiddle demo
If you have access to FormData you can use append method to change file name.
Refer this doc for more information.
var files = $("#fileUpload").get(0).files;
if (files.length > 0) {
var data = new FormData();
var ext = files[0].name.match(/\.(.+)$/)[1];
var fileName = Math.random().toString(36).substr(2, 19) + "." + ext;
// Add the uploaded image content to the form data collection
if (files.length > 0) {
//data.append("UploadedImage", files[0]); //if you want to pass default name
data.append("UploadedImage", files[0],fileName);
}
HTML code -
<input id="fileUpload" type="file" ng-file-accept="'.jpg , .jpeg ,.bmp , .gif ,.png'" accept="image/*" />

jQuery how to check if uploaded file is an image without checking extensions?

Newbie here. The problem is that I currently have written a method which checks uploaded file size and extension in order to validate it. However, checking extensions is not a solution as that kind of validation may cause a lot of problems. What I want to do is to check the actual file type and validate it without using extension method. I have tried to use jQuery file validator but to no avail... This is a snippet from my current code:
<input type='file' id='imageLoader' name='imageLoader' accept="image/*" data-type='image' />
Script:
App.Dispatcher.on("uploadpic", function() {
$(":file").change(function() {
if (this.files && this.files[0] && this.files[0].name.match(/\.(jpg|jpeg|png|gif)$/) ) {
if(this.files[0].size>1048576) {
alert('File size is larger than 1MB!');
}
else {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
}
} else alert('This is not an image file!');
});
function imageIsLoaded(e) {
result = e.target.result;
$('#image').attr('src', result);
};
});
It is called once the upload input changes and after validation it uploads and displays the image. For now, I only care about validation and any help or ideas would be greatly appreciated!
Try something like this:
JavaScript
const file = this.files[0];
const fileType = file['type'];
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png'];
if (!validImageTypes.includes(fileType)) {
// invalid file type code goes here.
}
jQuery
var file = this.files[0];
var fileType = file["type"];
var validImageTypes = ["image/gif", "image/jpeg", "image/png"];
if ($.inArray(fileType, validImageTypes) < 0) {
// invalid file type code goes here.
}
You don't need jquery here.
var mimeType=this.files[0]['type'];//mimeType=image/jpeg or application/pdf etc...
//ie image/jpeg will be ['image','jpeg'] and we keep the first value
if(mimeType.split('/')[0] === 'image'){
console.log('the file is image');
}
You can also create a function to check when a file is image.
function isImage(file){
return file['type'].split('/')[0]=='image');//returns true or false
}
isImage(this.file[0]);
Update (es6)
using es6 includes method, makes it even more simple.
const isImage = (file) => file['type'].includes('image');
Pls refer a related query here. The answer here suggests to load the image in an Image object and check for it's width and height properties to be non zero.
I think the technique can be used to solve your problem too.
I also worked out a fiddle for you to refer. Pertinent code below:
var img = new Image();
img.addEventListener("load",function(){
alert('success');
});
img.addEventListener("error",function(){
alert('error');
});
img.src = picFile.result;
Here is a quick tip if you just want to know if the file is an image:
var file = this.files[0];
var fileType = file["type"];
if (fileType.search('image') >= 0) {
...
}
What I want to do is to check the actual file type
Try accessing files[0].type property . See Using files from web applications
$(":file").on("change", function(e) {
console.log(this.files[0].type);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type='file' id='imageLoader' name='imageLoader' accept="image/*" data-type='image' />
If anyone comes here who is using jQuery Validator, a simple method would be:
jQuery.validator.addMethod(
"onlyimages",
function (value, element) {
if (this.optional(element) || !element.files || !element.files[0]) {
return true;
} else {
var fileType = element.files[0].type;
var isImage = /^(image)\//i.test(fileType);
return isImage;
}
},
'Sorry, we can only accept image files.'
);
which is then added to the .validate() function.
A lot of convoluted answers here.
Simply check whether the file has an image mime-type (which would be of the format image/...
const isImage = file => file.type.startsWith("image/")
$('#direct_upload').change(function() {
if (this.files[0].type.includes('image')) {
document.getElementById('attach_file').src = window.URL.createObjectURL(this.files[0])
} else {
console.log('it is a doc');
}
}
You could try to convert file type in string and after that slice this string like that:
if(String(file.type).slice(0, 6) === 'image/') {....some code}
Using jQuery version 3.3.1:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<label class="custom-file-label" for="customFile">Select Image</label>
<br>
<input type="file" class="custom-file-input" id="customFile">
</body>
<script>
$(document).ready(function() {
$(document).on("change", ".custom-file-input", function() {
var myImg = this.files[0];
var myImgType = myImg["type"];
var validImgTypes = ["image/gif", "image/jpeg", "image/png"];
if ($.inArray(myImgType, validImgTypes) < 0) {
alert("Not an image")
} else {
alert("Is an image")
}
});
});
</script>
</html>

Categories