I need to change this code so that the condition checks the file extensions of all the selected files from multiple select file input, this code only checks for one. Any way I can do this?
var file = document.getElementById('file');
var ext = file.value.substring(file.value.lastIndexOf('.') + 1);
if(ext!== "mp4" && ext!== "m4v" && ext!== "f4v") {
alert('not an accepted file extension');
return false;
}
<input id="file" name="uploaded[]" type="file" multiple />
Note I only bothered to get the last three characters of the string because you only have three letter file extensions. If you wanted you could use .split('.') to get an array of segments and choose the last element of that array.
var selection = document.getElementById('file');
for (var i=0; i<selection.files.length; i++) {
var ext = selection.files[i].name.substr(-3);
if(ext!== "mp4" && ext!== "m4v" && ext!== "fv4") {
alert('not an accepted file extension');
return false;
}
}
To get all the input elements within an array of dom elements use document.getElementsByName('uploaded[]').
For example in your case it would be something like:
var files = document.getElementsByName('uploaded[]');
for (var i = 0, j = files.length; i < j; i++) {
var file = files[i];
// do stuff with your file
}
Multiple files validation through javascript some() method.
function isVideo(film) {
const ext = ['.mp4', '.m4v', '.fv4'];
return ext.some(el => film.endsWith(el));
}
function fileValidation() {
let files = document.getElementById('file');
for (let i = 0; i < files.files.length; ++i) {
let fname = files.files.item(i).name;
if (!isVideo(fname)) {
alert("File extension not supported!");
return false;
}
}
}
<input id="file" name="uploaded[]" type="file" multiple onchange="fileValidation()" />
<input name="" id="yourinputfieldis" onchange="checkFile()" type="file" multiple = "multiple" accept = "*">
<script>
function checkFile() {
var x = document.getElementById("yourinputfieldis");
var txt = "";
document.getElementById("demo").innerHTML = txt;
if ('files' in x) {
if (x.files.length == 0) {
txt = "Select one or more files.";
} else {
for (var i = 0; i < x.files.length; i++) {
var file = x.files[i];
if ('name' in file) {
var ext = file.name.split('.').pop().toLowerCase();
if($.inArray(ext, ['gif','png','jpg','jpeg','doc','pdf','xlsx']) == -1) {
txt += "name: " + file.name + "<br>";
document.getElementById("yourinputfieldis").value = "";
if ('size' in file) {
txt += "size: " + file.size + " bytes <br>";
}
alert('You are trying to upload files which not allowed ' + "(" + file.name + " is invalid)");
}
}
}
}
}
else {
if (x.value == "") {
txt += "Select one or more files.";
} else {
txt += "The files property is not supported by your browser!";
txt += "<br>The path of the selected file: " + x.value;
}
}
}
</script>
Use this method to validate file types in aspx page,
<asp:FileUpload ID="fupload" name="fupload" runat="server" Class="form-control multi" accept="doc|docx|pdf|xls|xlsx" Width="270px" />
And I have used "MultiFile.js" plugin to choose Multiple file and Upload.
Related
How can I achieve gmail style of file uploading. From the below code i can select multiple file and am displaying selected files with anchor tag. How can i avoid duplicate files and adding and How to restrict the user to select only pdf and doc file? i need to alert if user select duplicate or if user select other than doc or pdf
<div class="container">
<form id="fileupload" action="#" method="POST" enctype="multipart/form-data">
<div class="row files" id="files1">
<h2>Files 1</h2>
Browse <input type="file" name="files1" multiple />
<br />
<ul class="fileList"></ul>
</div>
</form>
</div>
var filesToUpload = [];
var output = [];
$.fn.fileUploader = function (filesToUpload) {
this.closest(".files").change(function (evt) {
for (var i = 0; i < evt.target.files.length; i++) {
var found = false;
for(var j = 0; j < filesToUpload.length; j++){
if(evt.target.files[i].name == filesToUpload[j].name){
found = true;
break;
}
}
if(found == false){
filesToUpload.push(evt.target.files[i]);
}
else{
alert("duplicate");
}
}
for (var i = 0; i < evt.target.files.length; i++) {
var file= evt.target.files[i];
var found = false;
for(var j = 0; j < filesToUpload.length; j++){
if(evt.target.files[i].name == filesToUpload[j].name){
found = true;
break;
}
}
if(found == false){
var removeLink = "<a class=\"removeFile\" href=\"#\" data-fileid=\"" + i + "\">X</a>";
output.push("   <li><strong>",file.name,"</strong> ",removeLink,"</li> ");
}
else{
alert("duplicate");
}
}
$(this).children(".fileList").append(output.join(""));
});
};
$(document).on("click",".removeFile", function(e){
e.preventDefault();
var fileName = $(this).parent().children("strong").text();
// loop through the files array and check if the name of that file matches FileName
// and get the index of the match
for(i = 0; i < filesToUpload.length; ++ i){
if(filesToUpload[i].name == fileName){
//console.log("match at: " + i);
// remove the one element at the index where we get a match
filesToUpload.splice(i, 1);
}
}
//console.log(filesToUpload);
// remove the <li> element of the removed file from the page DOM
$(this).parent().remove();
});
$("#files1").fileUploader(filesToUpload);
$("#files2").fileUploader(filesToUpload);
$("#uploadBtn").click(function (e) {
e.preventDefault();
});
$.fn.fileUploader = function(filesToUpload) {
this.closest(".files").change(function(evt) {
var index;
for (var i = 0; i < evt.target.files.length; i++) {
index = filesToUpload.indexOf(evt.target.files[i]);
if (index > -1) {
filesToUpload.splice(index, 1);
}
}
for (i = 0; i < evt.target.files.length; i++) {
var filename = evt.target.files[i].name;
var valid_extensions = /(\.pdf|\.doc|\.docx)$/i;
if (valid_extensions.test(filename)) {
for (var i = 0; i < evt.target.files.length; i++) {
filesToUpload.push(evt.target.files[i]);
};
var output = [];
for (var i = 0, f; f = evt.target.files[i]; i++) {
var removeLink = "<a class=\"removeFile\" href=\"#\" data-fileid=\""+ i + "\">Remove</a>";
output.push("<li><strong>", escape(f.name),"</strong> - ", removeLink,"</li> ");
}
$(this).children(".fileList").append(output.join(""));
} else {
alert('Invalid File');
return false;
}
}
});
};
var filesToUpload = [];
$(document).on("click", ".removeFile", function(e) {
e.preventDefault();
var fileName = $(this).parent().children("strong").text();
// loop through the files array and check if the name of that file matches
// FileName
// and get the index of the match
for (i = 0; i < filesToUpload.length; ++i) {
if (filesToUpload[i].name == fileName) {
// console.log("match at: " + i);
// remove the one element at the index where we get a match
filesToUpload.splice(i, 1);
}
}
// console.log(filesToUpload);
// remove the <li> element of the removed file from the page DOM
$(this).parent().remove();
});
$("#files1").fileUploader(filesToUpload);
$("#files2").fileUploader(filesToUpload);
$("#uploadBtn").click(function(e) {
e.preventDefault();
});
Here, there is an example to show contents of one upload file.
.js
$scope.uploadFilename = function (files) {
if (!files[0]) {
return;
}
var reader = new FileReader();
reader.onload = function (e) {
var str = reader.result;
var csv = str.split(/\n/);
var headers = csv[0].split(',');
var str_result = '';
for (var i = 1; i < csv.length - 1; i++) {
var curline = csv[i].split(',');
var tmp = '' + curline[1];
if (i == csv.length - 2) {
str_result += tmp.split('"').join('');
} else {
str_result += tmp.split('"').join('') + '\n';
}
}
angular.element('#upload_keywords_list').val(str_result);
$scope.uploadedKeywordsCount = csv.length - 2;
};
reader.readAsText(files[0]);
};
.html
<div class="chosefile">
<div class="clearfix">
<input type="file" name="file" class="pull-left" onchange="angular.element(this).scope().uploadFilename(this.files)">
<textarea id="upload_keywords_list" class="form-control" rows="10"></textarea>
<div class="uploaded-keywords-count" ng-if="uploadedKeywordsCount > 0">
<strong>Total number: </strong>{{ uploadedKeywordsCount }}
</div>
</div>
</div>
I want to show contents of multi upload files.
Can you tell me the method how to do it?
And then, how to change the value of total number, when i edit the contents of textarea that I've already opened?
Thanks.
Hope this works.
I removed uploaded-keywords-count and textarea from your html. And added a new div
<div id="textAreaContainer"></div>
Also i made changes to your script. I wrapped your code inside for loop
Now, you can select multiple files, at once or one by one it doesn't matter.
And if you try to select the same file again, it warns you. and rejects the file again.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="fileApp" ng-controller="myCtrl">
<script>
var app = angular.module('fileApp', []);
app.controller('myCtrl', function($scope) {
var allFiles = [];
$scope.uploadFilename = function (files) {
if (!files[0]) {
return;
}
cnt = files.length;
for (var k = 0; k < cnt; k++) {
if(!allFiles.includes(files[k].name)) {
var reader = new FileReader();
reader.fileName = files[k].name;
allFiles.push(reader.fileName);
reader.onload = function (e) {
var str = e.target.result;
var csv = str.split(/\n/);
var headers = csv[0].split(',');
var str_result = '';
for (var i = 1; i < csv.length - 1; i++) {
var curline = csv[i].split(',');
var tmp = '' + curline[1];
if (i == csv.length - 2) {
str_result += tmp.split('"').join('');
} else {
str_result += tmp.split('"').join('') + '\n';
}
}
$scope.uploadedKeywordsCount = csv.length - 2;
var containerData = "";
containerData += '<div id="fileContent' + k + '"><textarea>' + str_result + '</textarea>';
containerData += '<span>' + $scope.uploadedKeywordsCount + '</span></div>'
var containerHtml = $(containerData);
angular.element('#textAreaContainer').append(containerHtml);
};
reader.readAsText(files[k]);
//console.log(files[k]);
} else {
alert('File already exists');
}
}
}
});
$(document).on('keyup', 'textarea', function(){
$(this).closest("div").find('span').html($(this).val().split(/\n/).length);
})
</script>
<div class="chosefile">
<div class="clearfix">
<input type="file" name="file" class="pull-left" onchange="angular.element(this).scope().uploadFilename(this.files)" multiple>
<div id="textAreaContainer"></div>
</div>
</div>
</div>
I forgot to tell you that i added a new script for your second question. Now you can edit the textarea, and the lines count changes.
I've downloaded the following opennsf. I would like to add for each document uploaded the option to delete if you choosed wrong. I managed to add a button in the script but I don't know how to link it to the attachment.
Here is the edited code:
var files = document.getElementById('ynFileUploadMulti').files;
var html = '';
if (files && files.length > 0) {
if(dojo.byId("ynFileUploadInfo").innerHTML == "" ) {
html = '<table id="ynFileUpload" class="xspDataTableFileDownload" style="width:100%;margin-bottom:1em">';
html += '<thead style="color:#545454;"><tr><th style="font-weight:bold;width:46px">Size</th><th style="font-weight:bold">Files to Upload</th><th style="font-weight:bold">Delete</th></tr></thead><tbody style="color:#a0a0a0">';
}
else{
html += dojo.byId("ynFileUploadInfo").innerHTML;
html = html.replace("</tbody></table>", "");
}
for (var i = 0; i < files.length; i++) {
var file = files[i];
var fileSize = 0;
if (file.size > 1024 * 1024)
fileSize = (Math.round(file.size / (1024 * 1024))).toString() + ' MB';
else
fileSize = (Math.round(file.size / 1024)).toString() + ' KB';
html += '<tr><td>'+fileSize+'</td><td>'+file.name+'</td><td ><button onclick="myFunction()">x</button></td></tr>'
}
html += '</tbody></table>';
}
dojo.byId("ynFileUploadInfo").innerHTML = html;
} catch (e) {
console.log("ynUpload_onchange: "+e);
}
This code is in the ynUploader_onchange() function. But I guess I need to touch the other function too (the ynUploader_worker(.....) function)?? How can I achieve this?
You can use the property "Allow Delete" in the File Download control or you can place a button on the xpage/cc with the following code to get a handle on the uploaded files
var attList = document1.getAttachmentList("AttachmentRT");
for(var i=0; i<attList.size(); i++)
{
var att:String = attList[i];
// Here you can process every uploaded file
}
AttachmentRT ist the name of the notesrichtext field bound to the File Download
I have a javascript which appends a string like 222222222222222 to another field (which will either be blank or already have numbers like 222222222222222 33333333333333) with a click of a button. Actually it's 15 digit IMEI of the phone. User has the option of submitting a single IMEI or bulk IMEI. When more then one IMEI is added to the bulk field by pressing the button from myVar1, the new IMEI gets inserted below the previous IMEI in the bulk field(myVar2).
Currently, I am using the below script to do this and it's working perfectly fine. The problem is that it doesn't check for duplicates before appending.
function append_myVar1_to_myVar2(){
var myVar1 = document.getElementById('myVar1_value').value;
var myVar2 = document.getElementById('myVar2_value').value;
if(document.getElementById('myVar2_value').value == ''){
document.getElementById('myVar2_value').value = myVar1;
}else{
document.getElementById('myVar2_value').value = document.getElementById('myVar2_value').value + "\r\n" + myVar1;
}
}
I have modified the script now as below (updated to include the first response, thanks to Brian) to check for duplicates, but it's not working. Request experts to have a look into it.
function append_myVar1_to_myVar2(){
var myVar1 = document.getElementById('myVar1_value').value;
var myVar2 = document.getElementById('myVar2_value').value;
if(document.getElementById('myVar2_value').value == ''){
document.getElementById('myVar2_value').value = myVar1;
}else{
var flag = 0;
var wordsarr = myVar2.split("\r\n");
for(var i = 0; i < wordsarr.length; i++)
{
if(wordsarr[i].value == myVar1)
{
flag = 1;
}
}
if(flag == 1)
{
alert('Value is duplicate.');
}
else{
document.getElementById('myVar2_value').value = document.getElementById('myVar2_value').value + "\r\n" + myVar1;
}
}}
Here is the html of the page:
<html>
<body>
<input id="myVar1_value" type="text" maxlength="15" name="myVar1_value">
<input id="IMEI_ADD" class="button_gray" type="button" onclick="append_myVar1_to_myVar2()" value="Add this IMEI to bulk entry" name="IMEI_ADD">
<p id="imei_bulk_field" class="form-row notes">
<textarea id="myVar2_value" class="input-text" rows="2" cols="5" placeholder="If you have more than one IMEI, insert them here by pressing the button above." name="myVar2_value"></textarea>
</p>
</body>
</html>
for(var i = 0; i < (myVar2.split("\r\n")).length; i++)
{
//here is wrong
if(myVar2[i].value == myVar1)
{
flag = 1;
}
You should change to
var wordsarr = myVar2.split("\n");
for(var i = 0; i < worsarr.length; i++)
{
if(wordsarr[i] == myVar1)
{
flag = 1;
}
}
if(flag == 1)
{
alert('Value is duplicate.');
}
Store splitted chunks ,and iterate over them:
var chunkArray = myVar2.split("\r\n");
for(var i = 0; i !== chunkArray.length; i++){
if(chunkArray[i] == myVar1){
flag = 1;
break;
}
}
var myVar2 = document.getElementById('myVar2_value').value;
Later...
if(myVar2[i].value == myVar1)
It looks like you are adding .value when you don't need to. Try:
if(myVar2[i] == myVar1)
This could be of assistance
function inArray(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
you could change the if with:
haystack[i].value == needle
I am a beginner in jquery so this may be stupid.
I want to take csv data from the user and transform it into json. Found a nice library but don't quite understand how the submitting is done in jquery.
For instance if I have a view
<script type="text/javascript" src="<?php echo site_url('public/js/jquery.js') ?>" ></script>
<script type="text/javascript" src="<?php echo site_url('javascript/main.js') ?>" ></script>
<div id="message"><p></p></div>
<form id="convertForm" name="convertForm" onsubmit="return false; ">
CSV<br /><textarea id="csv" name="csv" rows="10" cols="60"></textarea><br /><br />
JSON<br /><textarea id="json" name="json" rows="10" cols="60" readonly="readonly"></textarea><br /><br />
<input type="button" value="Convert" id="submitButton"/> <input type="reset" />
</form>
And the main.js file
function parseCSVLine (line)
{
line = line.split(',');
for (var i = 0; i < line.length; i++)
{
var chunk = line[i].replace(/^[\s]*|[\s]*$/g, "");
var quote = "";
if (chunk.charAt(0) == '"' || chunk.charAt(0) == "'") quote = chunk.charAt(0);
if (quote != "" && chunk.charAt(chunk.length - 1) == quote) quote = "";
if (quote != "")
{
var j = i + 1;
if (j < line.length) chunk = line[j].replace(/^[\s]*|[\s]*$/g, "");
while (j < line.length && chunk.charAt(chunk.length - 1) != quote)
{
line[i] += ',' + line[j];
line.splice(j, 1);
chunk = line[j].replace(/[\s]*$/g, "");
}
if (j < line.length)
{
line[i] += ',' + line[j];
line.splice(j, 1);
}
}
}
for (var i = 0; i < line.length; i++)
{
// remove leading/trailing whitespace
line[i] = line[i].replace(/^[\s]*|[\s]*$/g, "");
// remove leading/trailing quotes
if (line[i].charAt(0) == '"') line[i] = line[i].replace(/^"|"$/g, "");
else if (line[i].charAt(0) == "'") line[i] = line[i].replace(/^'|'$/g, "");
}
return line;
}
function csvToJson ()
{
var message = "";
var error = false;
var f = document.forms["convertForm"];
var csvText = f.elements["csv"].value;
var jsonText = "";
setMessage(message, error);
if (csvText == "") { error = true; message = "Enter CSV text below."; }
if (!error)
{
benchmarkStart = new Date();
csvRows = csvText.split(/[\r\n]/g); // split into rows
// get rid of empty rows
for (var i = 0; i < csvRows.length; i++)
{
if (csvRows[i].replace(/^[\s]*|[\s]*$/g, '') == "")
{
csvRows.splice(i, 1);
i--;
}
}
if (csvRows.length < 2) { error = true; message = "The CSV text MUST have a header row!"; }
else
{
objArr = [];
for (var i = 0; i < csvRows.length; i++)
{
csvRows[i] = parseCSVLine(csvRows[i]);
}
benchmarkParseEnd = new Date();
for (var i = 1; i < csvRows.length; i++)
{
if (csvRows[i].length > 0) objArr.push({});
for (var j = 0; j < csvRows[i].length; j++)
{
objArr[i - 1][csvRows[0][j]] = csvRows[i][j];
}
}
benchmarkObjEnd = new Date();
jsonText = JSON.stringify(objArr, null, "\t");
benchmarkJsonEnd = new Date();
f.elements["json"].value = jsonText;
benchmarkPopulateEnd = new Date();
message = getBenchmarkResults();
}
}
setMessage(message, error);
}
$(document).ready(function(){
$('#submitButton').on('click', function(){
console.log('i got here');
csvToJson;
});
});
This works perfectly but console.log is never shown.
And if I try to do something like return the jsonText from the csvToJson function and then append it to the second textarea, that doesn't work either.
function csvToJson ()
{
//same code here
return jsonText;
}
$(document).ready(function(){
$('#submitButton').on('click', function(){
console.log('i got here');
jsont = csvToJson();
$("#json").val(jsonT);
});
It's clearly something I don't get about submitting. Should I use jquery .submit() function ?
You are missing brackets when calling csvToJson inside the click handler.
Change:
$('#submitButton').on('click', function(){
csvToJson;
});
TO
$('#submitButton').on('click', function(){
csvToJson();
});
DEMO: http://jsfiddle.net/MRmJM/1/
One note: If CSV is separated by semi-colon (not uncommon) , parser code fails to create proper object