I have a code which creates a folder in my google drive and allows user to upload multiple files with file upload as a input.
Script.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script>
(function($){
function floatLabel(inputType){
$(inputType).each(function(){
var $this = $(this);
$this.focus(function(){
$this.next().addClass("active");
});
$this.blur(function(){
if($this.val() === '' || $this.val() === 'blank'){
$this.next().removeClass();
}
});
});
}
floatLabel(".floatLabel");
})(jQuery);
jQuery(".mail-btn").on("click touchstart", function () {
jQuery(this).addClass("fly");
that = this
setTimeout(function() {
jQuery(that).removeClass("fly");
}, 5400)
});
var rootFolderId = 'MYFOLDERID';
var numUploads = {};
numUploads.done = 0;
numUploads.total = 0;
// Upload the files into a folder in drive
// This is set to send them all to one folder (specificed in the .gs file)
function uploadFiles() {
//var allFiles = document.getElementById('myFiles').files;
var allFiles = document.querySelector('input[type=file]').files;
var applicantName = document.getElementById('pname').value;
if (!applicantName) {
window.alert('Missing applicant name!');
}
var applicantEmail = document.getElementById('email').value;
if (!applicantEmail) {
window.alert('Missing applicant email!');
}
var folderName = applicantName + ' ' + applicantEmail;
if (allFiles.length == 0) {
window.alert('No file selected!');
} else {
numUploads.total = allFiles.length;
google.script.run.withSuccessHandler(function(r) {
// send files after the folder is created...
for (var i = 0; i < allFiles.length; i++) {
// Send each file at a time
uploadFile(allFiles[i], r.folderId);
}
}).createFolder(rootFolderId, folderName);
}
}
function uploadFile(file, folderId) {
var reader = new FileReader();
reader.onload = function(e) {
var content = reader.result;
//document.getElementById('files1').innerHTML = 'uploaded '
+ file.name + '...';
//window.alert('uploading ' + file.name + '...');
google.script.run.withSuccessHandler(showSuccess)
.uploadFile(content, file.name, folderId);
}
reader.readAsDataURL(file);
//document.getElementById('Assessment-form').reset();
}
function showSuccess(e) {
$('#forminner').hide();
$('#success').show();
$('#Assessment-form').trigger("reset");
}
</script>
</body>
</html>
form.html
<input type="file" id="myFiles1" class="floatLabel" name="f1" multiple>
<input type="file" id="myFiles2" class="floatLabel" name="f2" multiple>
This allows me to upload multiple files using single file button (only using myFiles1). What I am trying is to upload files in same folder using multiple file buttons(myFiles1 and myFiles2). I tried to change
var allFiles = document.querySelector('input[type=file]').files;
with multiple things such as querySelectorAll but its not working.
Related
I'm using touchTouch lightbox library in order to preview the images in a lightbox for a post that user wants to send.
This library is used on my back-end and works flawlessly (since the images are in a folder already), but in the front-end there is a form where the user may upload up to 20 images. The images will show their preview after the user has uploaded them (but before they have sent the form) and I want them to be clickable which would open a lightbox library.
The problem is that the library can't find the images location because they are not uploaded just yet.
I thought about using ajax to upload the images into a temporary folder and then remove the folder and its content once the form is submitted. Could this work (without refreshing the page or submitting the form), or are there any better alternative solutions for this?
JavaScript code to upload the files and show their preview + initialize lightbox library upon loading:
function ImgUpload() {
var imgWrap = "";
var imgArray = [];
$('.upload__inputfile').each(function () {
$(this).on('change', function (e) {
imgWrap = $(this).closest('.upload__box').find('.upload__img-wrap');
var maxLength = $(this).attr('data-max_length');
var files = e.target.files;
var filesArr = Array.prototype.slice.call(files);
var iterator = 0;
filesArr.forEach(function (f, index) {
if (!f.type.match('image.*')) {
return;
}
if (imgArray.length > maxLength) {
return false
} else {
var len = 0;
for (var i = 0; i < imgArray.length; i++) {
if (imgArray[i] !== undefined) {
len++;
}
}
if (len > maxLength) {
return false;
} else {
imgArray.push(f);
var reader = new FileReader();
reader.onload = function (e) {
var html = "<div class='upload__img-box'><a href='" + f.name + "' class='light-box' data-group='gallery'><div style='background-image: url(" + e.target.result + ")' data-number='" + $(".upload__img-close").length + "' data-file='" + f.name + "' class='img-bg'><div class='upload__img-close'></div></div></a></div>";
imgWrap.append(html);
iterator++;
touchTouch(document.body.querySelectorAll('.light-box')); // Initialize the lightbox library
// Ajax script here to upload the images to a temporary folder?
}
reader.readAsDataURL(f);
}
}
});
});
});
Basically you could create a data-url from an uploaded image (before uploaded) which will allow you to access it locally and treat it like it was a regular image.
imgInp.onchange = evt => {
const [...files] = imgInp.files
if (files) {
files.forEach(function(file) {
var img = new Image();
img.src = URL.createObjectURL(file)
img.style.width = "200px"
container.appendChild(img)
// do your touchTouch initialization on the new elements
// touchTouch(img);
img.onclick = function() {
alert('lightbox');
}
})
}
}
<form>
<p>Choose Images, then click for lightbox.</p>
<input accept="image/*" type='file' id="imgInp" multiple />
</form>
<div id="container">
</div>
Let's try with given code (not tested):
ImgUpload();
function ImgUpload() {
var imgWrap = "";
var imgArray = [];
$('.upload__inputfile').each(function() {
$(this).on('change', function(e) {
imgWrap = $(this).closest('.upload__box').find('.upload__img-wrap');
var maxLength = $(this).attr('data-max_length');
var files = e.target.files;
var filesArr = Array.prototype.slice.call(files);
var iterator = 0;
filesArr.forEach(function(f, index) {
if (!f.type.match('image.*')) {
return;
}
if (imgArray.length > maxLength) {
return false
} else {
var len = 0;
for (var i = 0; i < imgArray.length; i++) {
if (imgArray[i] !== undefined) {
len++;
}
}
if (len > maxLength) {
return false;
} else {
imgArray.push(f);
var object_url = URL.createObjectURL(f)
var html = "<div class='upload__img-box'><a href='" + f.name + "' class='light-box' data-group='gallery'><div style='background-image: url(" + object_url + ")' data-number='" + $(".upload__img-close").length + "' data-file='" + f.name + "' class='img-bg'><div class='upload__img-close'></div></div></a></div>";
imgWrap.append(html);
iterator++;
setTimeout(function() {
touchTouch(document.body.querySelectorAll('.light-box')); // Initialize the lightbox library
});
// Ajax script here to upload the images to a temporary folder?
}
}
});
});
});
}
<form>
<p>Choose Images, then click for lightbox.</p>
<input accept="image/*" type='file' id="imgInp" class="upload__inputfile" multiple />
</form>
<div id="container">
</div>
Attempt to convert the data obtained from the File interface to Base64 or DataURL.then set img src='data:image/png;base64str'
are there any better alternative solutions for this?
Yes! I would recommend these js libraries
Filepond by PQINA and Dropzone.js
Be advised that they both have image preview but not lightbox feature. But with Dropzone.js, this Stack Overflow thread might help How to add popup image in to dropzone thumbnail?
My script has an HTML file upload button in which I can upload an image by selecting any. I am creating functionality to load a specific image by clicking a button. Like if I click a button the HTML file upload value should load this URL image.
Image 1
https://studysciences.com/wp-content/uploads/2020/05/Osteoarthritis-main.jpg
var $btnLoadMaskImage = $('#input-mask-image-file');
var $btnApplyMask = $('#btn-apply-mask');
var $btnClose = $('.close');
$btnLoadMaskImage.on('change', function() {
var file;
var imgUrl;
if (!supportingFileAPI) {
alert('This browser does not support file-api');
}
file = event.target.files[0];
if (file) {
imgUrl = URL.createObjectURL(file);
imageEditor.loadImageFromURL(imageEditor.toDataURL(), 'FilterImage').then(function() {
imageEditor.addImageObject(imgUrl).then(function(objectProps) {
URL.revokeObjectURL(file);
console.log(objectProps);
});
});
}
});
$btnApplyMask.on('click', function() {
imageEditor.applyFilter('mask', {
maskObjId: activeObjectId
}).then(function(result) {
console.log(result);
});
});
$btnClose.on('click', function() {
imageEditor.stopDrawingMode();
$displayingSubMenu.hide();
});
<input type="file" accept="image/*" id="input-mask-image-file">
Working DEMO environment: https://codepen.io/tester2020/pen/ExPEyER?editors=1001
Essential code:
var $newBtn = $('#newBtn');
$newBtn.on('click', function() {
// URL address of your image:
var imgUrl = 'https://i.ibb.co/BPfJmqM/Osteoarthritis-main.jpg';
var byteNumbers = new Array(imgUrl.length);
for (var i = 0; i < imgUrl.length; i++) {
byteNumbers[i] = imgUrl.charCodeAt(i);
}
var file = new File(byteNumbers, imgUrl, { type: "image/jpeg" });
imageEditor.loadImageFromURL(imageEditor.toDataURL(), 'FilterImage').then(function() {
imageEditor.addImageObject(imgUrl).then(function(objectProps) {
URL.revokeObjectURL(file);
console.log(objectProps);
});
});
});
I currently I have this piece of code which was originally a sample code online but edited slightly to fit my needs.
<input type="file" id="files" name="file" />
<span class="readBytesButtons">
<button>display injected files</button>
<span>
<div id="displayedText"></div>
function readBlob(opt_startByte, opt_stopByte) {
var files = document.getElementById('files').files;
console.log(files);
if (!files.length) {
alert('Please select a file!');
return;
}
//var file = files[0];
var reader = new FileReader();
reader.readAsText(files[0], "UTF-8");
reader.onload = function (evt) {
try {
var startWord = "inject";
var endWord = "];";
var injectedFilesString = evt.target.result.slice(evt.target.result.indexOf(startWord), evt.target.result.indexOf(endWord)) + "]";
var injectedFiles = injectedFilesString.split('[')[1].split(']')[0].split(', ');
document.getElementById("displayedText").innerHTML = injectedFiles
; }
catch(err) {
document.getElementById("displayedText").innerHTML = "<span style='color: red; font-weight: bold; font-family: verdana;'>This file does not have any injected files within it.</span>";
}
}
reader.onerror = function (evt) {
alert("error reading file");
}
}
document.querySelector('.readBytesButtons').addEventListener('click', function(evt) {
if (evt.target.tagName.toLowerCase() == 'button') {
var startByte = evt.target.getAttribute('data-startbyte');
var endByte = evt.target.getAttribute('data-endbyte');
readBlob(startByte, endByte);
console.log(files);
}
}, false);
This piece of code currently reads and displays a certain portion of a file which is selected by the file selector tool. How could I change this code so that I don't need the file selector and could print portions of a file using a method such as fileName.injected();
Thanks, let me know if you have any clarifications
I have an aspx page which already has a code for uploading file using "asp:FileUpload" and webform. On a different section of page, I want to add the functionality for a user to upload file. But i do not want to use webforms or "asp:fileupload".
So, I created an HTML file that i inject as an iframe inside a div tag on the aspx.
<div id="iUploadDoc" style="height:50px;">
<iframe name='FileUpload' id='FileUpload' class='iUploadFrame' width='100%' frameborder='0' border='0'src='DocUpload.htm'></iframe></div>
I set the EnablePageMethods to true.
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
And inside the HTML I made a form and with input type file.
<form method="POST" action="DocDetail.aspx.cs" id="docUpload" enctype="multipart/form-data">
<div>
<label for="fileUpload" class="inputLabel">Upload File</label>
<input type="file" id="fileUpload" name="files"/>
</div>
</form>
<div id="progUpload" style="display: none;">
<p class="uploadBox">Uploading...</p>
</div>
<span id= "selectedFile" style="display: none;"></span><span id="fileName" style="display: none;"></span>
Now, I dont know what to put in the "action" param of form.
First on the iframe, below is the script i wrote:
window.onload = load;
function uploadDocFile() {
var prog = document.getElementById("progUpload");
prog.style.cssText = 'display: block;';
var x = document.getElementById("fileUpload");
var txt = "";
var filePath = "";
var fileName = "";
if (x.value == "") {
txt += "Select a file.";
document.getElementById("selectedFile").innerHTML = txt;
} else {
filePath = x.value;
fileName = filePath.replace(/^.*[\\\/]/, '');
txt += "<br>Selected file: ";
document.getElementById("selectedFile").innerHTML = txt;
document.getElementById("fileName").innerHTML = fileName;
}
var formInfo = document.getElementById("docUpload");
document.getElementById("docUpload").style.display = "none";
window.parent.getFormData(formInfo, x ,x.value, fileName);
}
function load() {
var e = document.getElementById("fileUpload");
//var formInfo = document.getElementById("docUpload");
//fakeClick();
e.onchange = function () {
uploadDocFile();
}
}
Then on the parent page, below is the script i wrote.
DocUpload.prototype.uploadFileDoc= function (formInfo, uploadedFile, fileInfo, lastModifiedDate, name, extension, size, type) {
//blacklitsType is an array of types of file (similarly for blacklistExt) that should not be allowed to upload
if (indexOf.call(blackListType, type) < 0 && indexOf.call(blackListExt, extension) < 0) {
var idParams = { OiD: ordId, pID: pId, QID: qId }
var files = uploadedFile.files;
var fileEntries = [];
for (j = 0, len1 = files.length; j < len1; j++) {
file = files[j];
if (file.getAsEntry) {
entry = file.getAsEntry();
} else if (file.webkitGetAsEntry) {
entry = file.webkitGetAsEntry();
}
if (entry) {
isFyl = entry.isFile;
if (!isFyl) {
alert("You can not upload a folder. Uploading files (if present).");
} else {
fileItem = file.getAsFile();
fileEntries.push(fileItem);
}
} else if (!file.type && file.size % 4096 === 0) {
alert("You can not upload a folder. Uploading files (if present).");
} else {
fileEntries.push(file);
}
}
PageMethods.UploadDocument(fileEntries[0], idParams, function (res) {
if (res == true) {
alert("File uploaded successfully.");
} else {
alert("File upload failed.");
}
}, function (err) {
alert("ERROR: " + err._message);
});
} else {
window.alert('You cannot upload incorrect file types.');
}
return;
};
DocUpload.prototype.getFormData = function (formInfo, uploadedFile, fileInfo, nameInfo) {
var currDate, extension, lastModifiedDate, name, nameArr, size, type;
currDate = new Date();
lastModifiedDate = currDate;
type = '';
size = 512;
name = nameInfo;
nameArr = name.split(".");
extension = nameArr[nameArr.length - 1];
DocUpload.prototype.uploadFileDoc(formInfo, uploadedFile, fileInfo, lastModifiedDate, name, extension, size, type);
};
window.getFormData = DocUpload.prototype.getFormData;
The transfer of attributes of form from iframe to parent page work just fine. But how should i post it as file using PageMethod. Below is the page method in my code behind:
[System.Web.Services.WebMethod()]
[System.Web.Script.Services.ScriptMethod(UseHttpGet = false)]
public static bool UploadDocument(HttpPostedFileBase uploadedFile,IdParams idParams) {
bool err = false;
try{
//code
err= true;}
catch(Exception ex){err = false;}
return err;
}
No matter how much tried, either I keep getting error regarding HTTPPostedFileBase or Serialization of child not allowed.Below are only some of the errors i keep getting (not at the same time):
No parameterless constructor System.Web.HttpPostedFileBase aspx, OR
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter
What should i do?
HTML Code
<input type="file" accept="image/*" multiple webkitdirectory mozdirectory msdirectory odirectory directory id="fileURL"/>
Javascript Code:
var files,
file,
extension,
sum,
input = document.getElementById("fileURL"),
output = document.getElementById("fileOutput"),
holder = document.getElementById("fileHolder")
sizeShow = document.getElementById("filesSize");
input.addEventListener("change", function (e) {
files = e.target.files;
output.innerHTML = "";
sum = 0;
for (var i = 0, len = files.length; i < len; i++) {
file = files[i];
extension = file.name.split(".").pop();
if(extension=="jpg"||extension=="png"){
var size = Math.floor(file.size/1024 * 100)/100;
sum = size+sum;
output.innerHTML += "<li class='type-" + extension + "'>"+file.webkitRelativePath + file.name + " (" + size + "KB)</li>";
}else{
file.remove();
}
}
if(sum<1024*1024){
sizeShow.innerHTML = Math.floor(sum/1024*100)/100 + " MB";
}else if(sum>1024*1024){
sizeShow.innerHTML = Math.floor(sum/1024*1024*100)/100 + " GB";
}
}, false);
How do i get just the image in the file upload? accept="image/*" doesn't work for directory.
This does work but the statement file.remove() doesn't work at all.
I guess the input:file is read-only.
How do i solve this?
You can set input.files to a FileList (obtained from e.g. drag and drop), but you cannot create/modify a FileList. So you cannot modify the files of an input to e.g. only contain images.
What you can do, though, is uploading manually (through ajax), and only send files that have a type starting with "image/". See http://jsfiddle.net/WM6Sh/1/.
$("form").on("submit", function(e) {
e.preventDefault();
var files = $(this).find("input").prop("files");
var images = $.grep(files, function(file) {
return file.type.indexOf("image/") === 0; // filter out images
});
var xhr = new XMLHttpRequest();
xhr.open("POST", "/", true);
$(xhr).on("readystatechange", function(e) {
if(xhr.readyState === 4) {
console.log("Done");
}
});
var data = new FormData();
$.each(images, function(i) {
data.append(i, this); // append each image file to the data to be sent
});
console.log(
"Sending %d images instead of all %d files...",
images.length,
files.length
);
xhr.send(data);
});