append an array of blobs to a google doc using google script - javascript

I have a script where users can submit pictures to a google doc, but when I upload multiple pictures with the file input, google script doesnt append all the images. How would i rewrite my code so it appends all the images i selected with the <input type="file" multiple />
Is theForm.theFile an array of all the pictures i uploaded? because theForm.theFile[0] does not work.
code.gs:
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function serverFunc(theForm) {
doc = DocumentApp.openById("my top-secret id...");
var img=doc.appendParagraph(theForm.theFile.getName()+":\n").setIndentStart(4).appendInlineImage(theForm.theFile)
//resize image to fit in page if necessary
while(img.getWidth()>750){
img.setWidth(img.getWidth()/1.1).setHeight(img.getHeight()/1.1)
}
}
index.http:
<form style="outline:2px solid blue;">
<input type="file" name="theFile" multiple />
<input type="button" value="UpLoad" id="button" onclick="google.script.run.serverFunc(this.parentNode)" />
</form>

Works with http://www.fyneworks.com/jquery/multiple-file-upload/#. You can then access each file through:
for (i = 0; i < theForm.theFile.length-1; i++) {
var blob = theForm.theFile[i];
var file = folder.createFile(blob);
}
I would also recommend looking into this example but using the DocsList Service instead:
https://developers.google.com/apps-script/guides/html/communication#forms
Hope this helps you get your head around it.

Related

Google Scripts/HTML/JavaScript Upload File to Folder Error Argument cannot be null: blob

I am creating an online HTML form that gives people the option to upload a file. I am using google sheets to collect the data so I am using their google scripts feature. When I run my code everything works, meaning I get data inserted into cells, but not the file upload. Here is my Google Scripts code for the file upload:
function doGet(request) {
return HtmlService.createTemplateFromFile('Index')
.evaluate();
}
/* #Include JavaScript and CSS Files */
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
function uploadFiles(data){
var folder = DriveApp.getFolderById('1pp1ELzGa2fZqU4IHAasZMHsmYx19pnYv');
var createFile = folder.createFile(data.image);
return createFile.getUrl();
}
From what I can tell the problem is at the data.image. This is where I am trying to retrieve my image so I can upload it into the folder. It must be that uploadFiles(data) is not properly bringing in data.
Here is the HTML and JavaScript:
<form id="myForm" onsubmit="handleFormSubmit(this)">
<h1 class="h4 mb-4 text-center" style="text-align:center"> <center>File Upload Testing</center></h1>
<table>
<tr>
<td colspan="11"><input type="file" id="image"></td>
</tr>
<input type="hidden" id="fileURL" name="fileURL">
</table>
<button type="submit" class="button button1" id="submitBtn">Submit</button>
</form>
<script>
document.getElementById('submitBtn').addEventListener('click',
function(e){
google.script.run.withSuccessHandler(onSuccess).uploadFiles(this.parentNode);;}
)
function onSuccess(data){
document.getElementById("fileURL").value = data;
}
</script>
I have a feeling that the e parameter is not retrieving the data above, however I don't really understand how it works. It could also be this.parentNode that's not grabbing the fike.
I am using the onSuccess function to retrieve the link so I can put it into my google sheet for quick access.
This is the error I receive;
Here is a link to the google sheet. To reach google scripts go to 'Tools -> Script Editor'.
https://docs.google.com/spreadsheets/d/16w8uB4OZHCeD7cvlrUv5GHP72CWxQhO1AAkF9MMSpoE/edit?usp=sharing
Here is another technique I attempted to use:
Javascript:
function uploadthis(fileForm){
const file = fileForm.image.files[0];
const fr = new FileReader();
fr.onload = function(e) {
const obj = {
// filename: file.name
mimeType: file.type,
bytes: [...new Int8Array(e.target.result)]
};
google.script.run.withSuccessHandler((e) => console.log(e)).uploadFiles(obj);
};
fr.readAsArrayBuffer(file);
}
Google Script:
function uploadFiles(data){
var file = Utilities.newBlob(data.bytes, data.mimeType); // Modified
var folder = DriveApp.getFolderById('1pp1ELzGa2fZqU4IHAasZMHsmYx19pnYv');
var createFile = folder.createFile(file);
return createFile.getId(); // Added
}
Thank you!

I want to know how i can from the path of the file selected use the same path to download the XML

I have a Html form that has a button capable of generating a XML file and downloading it to the users computers.
This is my XML.js file that writes all xml information and then donwloads the file to the user computer.
function downloadData(contentType,data,filename){
"use strict";
var link=document.createElement("A");
link.setAttribute("href",encodeURI("data:"+contentType+","+data));
link.setAttribute("style","display:none");
link.setAttribute("download",filename);
document.body.appendChild(link); //needed for firefox
console.log(link.outerHTML);
link.click();
setTimeout(function(){
document.body.removeChild(link);
},1000);
}
Function that gets the answers from the form
function fromToXml(form){
"use strict";
var xmldata=['<?xml version="1.0" encoding="UTF-8"?>'];
var inputs=form.elements;
xmldata.push("<AssetInfo>");
// file name*****************************
for(var i=0;i<inputs.length;i++){
if(inputs[i].value){
xmldata.push(" <customMetaData>");
xmldata.push(" <key>"+inputs[i].placeholder+"</key>");
xmldata.push(" <value>"+inputs[i].value+"</value>");
xmldata.push(" </customMetaData>");
}
}
xmldata.push("</AssetInfo>");
return xmldata.join("\n");
}
function download(frm){
"use strict";
var data=fromToXml(frm);
console.log(data);
// file name
downloadData("text/xml",data,"hello.xml");
}
HTML Button that calls the funtion inside XML.js
<button class="button" type="button" onclick="download(this.form)"
id="input">GerarXML</button>
HTML Button that asks the user to select a file
<input type="file" id="fileinput" nwdirectory multiple />
Need a back-end service in php that reads the file name and then store it in variable, and when generate the xml call the same variable.

Display shapeFile on leaflet map using an uploaded file.zip

I'm trying to display a shape file from Brazil on my leaflet map, this shape file is inside a .zip that contains: .dbf, .prj, .sbn, .sbx, .shp and .shx files. To do that, I'm using: https://github.com/calvinmetcalf/leaflet.shapefile
I have the .zip file at my local computer so I simply made:
HTML
<button ng-click="addShape()"> Brasil Shape File </button>
JS
var mymap = L.map('mapid').setView([-12.85, -50.09], 4);
$scope.addShape = function () {
var shpfile = new L.Shapefile('scripts/ShapeFiles/Brasil.zip');
shpfile.addTo(mymap);
}
Now I want to make the user upload the .zip to show it on the map exactly like whats happening here:
http://leaflet.calvinmetcalf.com/#3/32.69/10.55
But I can't figure this out... All I have found on the internet is posting the .zip file to an url. I need to use the file right after the user "uploaded" it to the browser.
On the code bellow the user can upload some file and POST it, I tried to console.log the supposed objects that contains the .zip file before sending it but I couldn't find it inside the objects:
HTML
<body ng-controller="FileUploadCtrl">
<div class="row">
<label for="fileToUpload">Select a File to Upload</label><br />
<input type="file" ng-model-instant id="fileToUpload" multiple onchange="angular.element(this).scope().setFiles(this)" />
</div>
<input type="button" ng-click="uploadFile()" value="Upload" />
</body>
JS
scope.setFiles = function(element) {
scope.$apply(function(scope) {
console.log('files:', element.files);
// Turn the FileList object into an Array
scope.files = []
for (var i = 0; i < element.files.length; i++) {
scope.files.push(element.files[i])
}
scope.progressVisible = false
});
};
scope.uploadFile = function() {
var fd = new FormData()
for (var i in scope.files) {
fd.append("uploadedFile", scope.files[i])
}
var xhr = new XMLHttpRequest()
xhr.upload.addEventListener("progress", uploadProgress, false)
xhr.addEventListener("load", uploadComplete, false)
xhr.addEventListener("error", uploadFailed, false)
xhr.addEventListener("abort", uploadCanceled, false)
xhr.open("POST", "/fileupload")
scope.progressVisible = true
xhr.send(fd)
}
source fiddle: danielzen
On this exemple, inside the functions 'setFiles' and 'uploadFile', when I console.log(fd) I get: fd: [object FormData] and console.log(element.files):
element.files[0] File {name: "Brasil (1).zip", lastModified: 1492436239000, lastModifiedDate: Mon Apr 17 2017 10:37:19 GMT-0300 (BRT), webkitRelativePath: "", size: 5988862…}
But I can't find the original .zip file that was uploaded, maybe because this is not the right way to do it...
If someone knows a way to get this .zip file or have access to this example source and can share with me I'll be very thankful.
I managed to solve this by using an arrayBuffer for the shapefile as it is specified here. I figured that out reading about this issue.
Here is my code:
HTML
<div id="mapid" style="width: 800px;float: left;">
</div>
<form action='#' onsubmit="return false;">
<input type='file' id='fileinput'>
<input type='button' id='btnLoad' value='Load' onclick='loadFile();'>
</form>
JS
function loadFile() {
input = document.getElementById('fileinput');
if (!input.files[0]) {
bodyAppend("p", "Please select a file before clicking 'Load'");
}
else {
file = input.files[0];
fr = new FileReader();
fr.onload = receiveBinary;
fr.readAsArrayBuffer(file);
}
function receiveBinary() {
result = fr.result
var shpfile = new L.Shapefile(result);
shpfile.addTo(mymap);
}
}
I use angular 12... and I can upload file with Shapefile.js https://github.com/calvinmetcalf/shapefile-js
You can see my code in https://gitlab.com/-/snippets/2141645

How To Include a google apps script in a html page,that has uploading functionality on google Drive

I just want to collect a files from users (like resume) & store on my google drive. That is working file from google apps script like below.I want to add this form to my html page. Which is provided by google as form URL
https://script.google.com/macros/s/AKfycbx8w-Um_pIWx8A1S_3R2CrSYhQqyLF6tyYJOQuUHdFT5jqBFP0/exec
want to add in shouttoday.com site's page.
i also tried include as js script,or iframe but not working.
There is to files as ---
server.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(form) {
try {
var dropbox = "Student Files";
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var blob = form.myFile;
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + form.myName);
return "File uploaded successfully " + file.getUrl();
} catch (error) {
return error.toString();
}
}
form.html
<form id="myForm">
<input type="text" name="myName" placeholder="Your name..">
<input type="file" name="myFile">
<input type="submit" value="Upload Resume"
onclick="this.value='Uploading..';
google.script.run.withSuccessHandler(fileUploaded)
.uploadFiles(this.parentNode);
return false;">
</form>
<div id="output"></div>
<script>
function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<style>
input { display:block; margin: 20px; }
</style>
having url app script url: https://script.google.com/macros/s/AKfycbx8w-Um_pIWx8A1S_3R2CrSYhQqyLF6tyYJOQuUHdFT5jqBFP0/exec
But Don't know how to embedded this app (form) in my html page.
You need to use google developer console for this. It have programming example available for the same. So, that will really help you.

Get text file content using javascript

I've tried use javascript to open text file and get his name and his content, so right now I'm stuck at string, because I used input - type file to get directory / path.
Anyway, my question what is wrong in the next code, and how can i get text file content using javascript?
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Display Text Files</title>
<script type="text/javascript">
var str = document.getElementById('txt').value;
function display() {
if (str != "") {
var filename = str.split("/").pop();
document.getElementById('filename').innerHTML = filename;
}
}
</script>
</head>
<body>
<form method="get" action="#" >
<input type="file" accept="text/plain" id="txt" />
<input type="submit" value="Display Text File" onclick="display();" />
</form>
</body>
</html>
EDIT: I also wanna disable in input file the all files opition (*) to text files only (.txt).
Thanks!
Modern browsers implementing FileReader can do this. To test your browser check if window.FileReader is defined.
Here is some code I wrote only this morning to do just this. In my case I simply drag a file onto the HTML element which is here referenced as panel.in1 but you can also use <input type="file" /> (see the reference below).
if (window.FileReader) {
function dragEvent (ev) {
ev.stopPropagation ();
ev.preventDefault ();
if (ev.type == 'drop') {
var reader = new FileReader ();
reader.onloadend = function (ev) { panel.in1.value += this.result; };
reader.readAsText (ev.dataTransfer.files[0]);
}
}
panel.in1.addEventListener ('dragenter', dragEvent, false);
panel.in1.addEventListener ('dragover', dragEvent, false);
panel.in1.addEventListener ('drop', dragEvent, false);
}
It is the reader.onloadend function which gets the text of the file which you recover in the event handler as this.result.
I got most of the mechanism on how to do this from MDN : https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

Categories