WebApp Google Script to collect data and upload a file - forms

I have got some code from another user in this fourm, but the code is uploading the file but not appending the textbox filed data and uploaded file link to the sheet.
i just want to have file upload and details regarding the file to be entered in the textboxes (present code is for name and email- that can be modified later for capturing other data) and the text box data along with the link of the file being uploded to be appended in the file containing the script.
form.html is as below:
<!-- Include the Google CSS package -->
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<!-- You can also include your own CSS styles -->
<style>
form { margin: 40px auto; }
input { display:inline-block; margin: 20px; }
</style>
<script>
// The function will be called after the form is submitted
function uploadFile() {
document.getElementById('uploadFileButton').value = "Uploading File..";
google.script.run
.withSuccessHandler(fileUploaded)
.uploadFiles(document.getElementById("labnol"));
return false;
}
// This function will be called after the Google Script has executed
function fileUploaded(status) {
document.getElementById('labnol').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<!-- This is the HTML form -->
<form id="labnol">
<!-- Text input fields -->
<input type="text" id="nameField" name="myName" placeholder="Your name..">
<input type="email" id="emailField" name="myEmail" placeholder="Your email..">
<!-- File input filed -->
<input type="file" name="myFile">
<!-- The submit button. It calls the server side function uploadfiles() on click -->
<input type="submit" id="uploadFileButton" value="Upload File"
onclick="this.value='Uploading..';uploadFile();return false;">
</form>
<!-- Here the results of the form submission will be displayed -->
<div id="output"></div>
code.gs is a s below:
/* The script is deployed as a web app and renders the form */
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html')
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
// This is important as file upload fail in IFRAME Sandbox mode.
}
/* This function will process the submitted form */
function uploadFiles(form) {
try {
/* Name of the Drive folder where the files should be saved */
var DMS = "Test Form Submissions";
var folder, folders = DriveApp.getFoldersByName(DMS);
/* Find the folder, create if the folder does not exist */
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(DMS);
}
/* Get the file uploaded though the form as a blob */
var blob = form.myFile;
var file = folder.createFile(blob);
//Allocate variables for submissions in sheet
var namerecord = form.myName;
var emailrecord = form.myEmail;
/* Set the file description as the name of the uploader */
file.setDescription("Uploaded by " + form.myName);
/* Return the download URL of the file once its on Google Drive */
return "File uploaded successfully " + file.getUrl();
var uploadURL = file.getUrl();
var url = "https://docs.google.com/spreadsheets/d/1Kk8uvMHC506UVuhjzsvKka-RTp5OEjWV-yeoWxeV5b4/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Inward");
ws.appendRow([namerecord,emailrecord,uploadURL]);
/*var googsheet =
SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1N80542YrEAT6Llq6k2vzDdkSO938csVv28UtUCNlpFU/edit?usp=sharing');
return "started";
var sheet = googsheet.getSheetName('Inward');
sheet.appendRow([namerecord,emailrecord,uploadURL]);
return "completed";
*/
//
} catch (error) {
/* If there's an error, show the error message */
return error.toString();
}
//Open spreadsheet based on URL
}
Please help in this regard. I am new to scripting and web apps.

Issue:
Function doGet contains a return statement after uploading the file and before appending the data to the spreadsheet:
return "File uploaded successfully " + file.getUrl();
This statement ends this function execution, so the script never get to the append data part.
Solution:
Assuming that you have access to this spreadsheet (variable url) and that this spreadsheet contains a sheet called Inward, your data should be successfully appended to the spreadsheet as long as the return statement is commented out/removed, or, if you want the page to return File uploaded successfully {fileUrl}, moved to the end of your try block:
ws.appendRow([namerecord,emailrecord,uploadURL]);
return "File uploaded successfully " + file.getUrl();

Related

Powershell webinvoke with Google Script webapp

Is there a way to web invoke from PowerShell connection to web app created in google app script ?
When im running the request on normal sites I will receive back information containing Forms[], Images[], InputFields[] etc. However when I'm trying to run the same request on a https://script.google.com/a/macros/ web app all those fields are blank and i can only see a variable called el linking to field called sandboxFrame.
The app is a simple upload site to one of my google folders, everything is working when I'm in browser. I'm trying to automate the process through PowerShell script
HTML file
<!DOCTYPE html>
<html>
<body>
<input name="file" id="files" type="file" multiple>
<input type='button' value='Upload' onclick='getFiles()'>
</body>
<script>
function getFiles() {
const f = document.getElementById('files');
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
google.script.run.withSuccessHandler((id) => {
console.log(id);
}).saveFile(obj);
}
fr.readAsDataURL(file);
});
}
</script>
</html>
GS script
function saveFile(obj) {
var folder = DriveApp.getFolderById('1w586veZcOZN_NnB90jaTZ12DF-jP005u');
var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
return folder.createFile(blob).getId();
}
You would need to take advantage of the doPost function.
I assume you already know about the doGet function, but there is another function that you can use as part of a web app called doPost. This allows you to post data using something like the following from powershell:
Invoke-WebRequest https://script.google.com/a/macros/[SCRIPTID]?[QUERYSTRING] -Method POST
Where the [QUERYSTRING] is something like:
name=bartosz&stack=BartoszWolas&reputation=1000
Then within the doPost on the web app side you would write a function like this:
function doPost(e) {
const name = e.parameter.name; // bartosz
const stackAlias = e.parameter.stack; // BartoszWolas
const reputation = e.parameter.reputation; // 1000
}
Reference
web app

Google Apps Script HTMLService display confirmation page after form submit

I created a web app form using Google Apps Script and the HTMLService.
It is a one-page form with a submit button at the bottom.
When submitted, the form validates whether the data input into the form is valid, and if valid, it logs the form data to a spreadsheet.
That all works so far.
I now need the user to be sent to a confirmation page, and the confirmation page needs to be able to have parameters passed to it (to display certain information on the confirmation page).
main.gs:
function doGet(e) {
var template = HtmlService.createTemplateFromFile('form');
return template.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function processFormSubmission(formData) {
Logger.log('starting processPoRequest');
Logger.log('po: ' + JSON.stringify(formData, null, 2));
// code for appending data to sheet here
}
form.html:
<!DOCTYPE html>
<form id="form1" name="form1">
<label for="info" id="info_label">Info</label>
<input id="info" name="info" type="text">
<input class="btn" id="button" onclick="onClickFunctions(document.getElementById('form1'))" type="submit" value="Submit">
</form>
<script>
function onClickFunctions(formData) {
console.log('starting onClickFunctions');
var allDataValid = validateForm(formData);
if (allDataValid === true) {
google.script.run.withSuccessHandler().processFormSubmission(formData);
}
}
function validateForm(form) {
console.log('starting validateForm');
var errors = 0;
var element = document.getElementById('info');
if (!form.info) { element.classList.add("validation_error"); errors++; if (errors === 1) element.focus(); }
else element.classList.remove("validation_error");
if (errors > 0) return false;
else return true;
}
</script>
confirmation.html:
<!DOCTYPE html>
<?!= confirmationMessage ?>
I don't know what to put in .withSuccessHandler() to make it so that the user is brought to the confirmation page.
I've Googled this extensively and found these results on Stack Overflow, and each one suggests a different solution, but none of them actually include complete working code for a solution:
Possible solutions using doPost:
Send form by email and track responses in spreadsheet
HtmlService doPost With Google Docs Form
HtmlService doPost
I messed around with doPost but I couldn't figure out how to get it to be invoked, and I couldn't find any official documentation in the HTMLService docs.
Possible solution using the link to the web app in an a href:
href in HtmlService
If my button was a link that looked like a button, I'm not sure how I would execute the form validation function when the link is clicked.
I have done this two different ways.
had a hidden statement that gets shown, and the form gets hidden.
or
use .withSuccessHandler(google.script.host.close()), but have the processFormSubmission function open a new dialogue.

Google Script Form with uploads, how to connect to spreadsheet

Hi the below script has allowed me to upload files to Google drive however I can not seem to get the data entered in 'Name' and 'Date" to enter in to a spreadsheet.
Can anyone help me create or link a spreadsheet for the data to populate into.
Thanks
code.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(form) {
try {
var dropbox = "Operation Overview";
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folder.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var blob = form.myFile;
var file = folders.createFile(blob);
file.setDescription("Uploaded by "+ form.myName);
return "File uploaded successfully ";
} catch (error) {
return error.toString();
}
}
form.html
<form id="myForm">
<input type="text" name="myName" placeholder="Your name.">
<input type="text" name="myDate" placeholder="Date.">
<input type="file" name="myFile">
<input type="submit" value="Upload File"
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>
You need to use the Spreadsheet Service:
Google Documentation - Apps Script Spreadsheet Service
You can use Append Rows:
Append Rows
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// Appends a new row with 2 columns to the bottom of the
// spreadsheet containing the values in the array
sheet.appendRow(["Jackson Jones", "jJones#email.com"]);
The above example uses the getActiveSpreadsheet() method. You won't be using that. You need a reference to the file.
You can open a spreadsheet file by id, or url.
Google Documentation - Open a Spreadsheet by ID
// The code below opens a spreadsheet using its ID and logs the name for it.
// Note that the spreadsheet is NOT physically opened on the client side.
// It is opened on the server only (for modification by the script).
var ss = SpreadsheetApp.openById("abc1234567");
Logger.log(ss.getName());
Notice the Logger.log() statement. To view the log, use the View menu in the Apps Script code editor.
It's critical to understand, that SpreadsheetApp.openById() returns a CLASS. It returns the SPREADSHEET CLASS
Google Documentation - Spreadsheet Class
Once you get the Spreadsheet Class, then you can take the next step and use methods available to the Spreadsheet Class.
var ss = SpreadsheetApp.openById("abc1234567");
Logger.log(ss.getName());
ss.appendRow(["Jackson Jones", "jJones#email.com"]);
In the above example, the data is hard coded, but you need variables instead of the constant values in double quotes.
So you need to get the data out of the form object, and into variables or a direct reference.
ss.appendRow([form.myName, "jJones#email.com"]);
I did check your code, and form.myName did return the name I entered into the name field.

show image on client before upload on server in gwt

I would like to show an image and its dimensions on the client before uploading it to the server. Whenever I try to create an Image widget of gwt ext, it doesn't accept a local file (on the file system). It only accepts http requests. I also tried String img = GWT.getHostPageBaseURL() + "image_name" and the replace function but with same result. Finally I moved to ImagePreloader but its also needs a URL.
ImagePreloader.load("URL of image", new ImageLoadHandler()
{
public void imageLoaded(ImageLoadEvent event)
{
if (event.isLoadFailed())
Window.alert("Image " + event.getImageUrl() + "failed to load.");
else
Window.alert("Image dimensions: " + event.getDimensions().getWidth() + " x " + event.getDimensions().getHeight());
}
});
Can someone suggest a solution that doesn't include uploading the image first?
Have a look at this related question and answer:
Preview an image before it is uploaded
You can include it using JSNI. I'm now aware of a solution within GWT.
Just found gwtupload which claims to be able to preview images before uploading them.
Please take a look at the sample JS code below:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#imgInp").change(function(){
readURL(this);
});
and the associated HTML:
<form id="form1" runat="server">
<input type='file' id="imgInp" />
<img id="blah" src="#" alt="your image" />
</form>

Uploading file using Google Apps Script using HtmlService

How can I upload files to google drive?
I want to create a web app using google app script - htmlservice.
I don't know how to point form in html to existing google app script.
I am having hard time to find a right example in google documentation.
I found hundreds of examples using UI but according to https://developers.google.com/apps-script/sunset it will be deprecated soon.
Thank you in advance!
Janusz
<html>
<body>
<form>
<input type="file"/>
<input type="button">
</form>
</body>
</html>
Script
function doGet() {
return HtmlService.createHtmlOutputFromFile('myPage');
}
function fileUploadTest()
{
var fileBlob = e.parameter.upload;
var adoc = DocsList.createFile(fileBlob);
return adoc.getUrl();
}
Have the button run the server side function using google.script.run, passing in the entire form as the only parameter. (Inside the button's onClick, 'this' is the button, so 'this.parentNode' is the form.) Make sure to give the file input a name.
<html>
<body>
<form>
<input type="file" name="theFile">
<input type="hidden" name="anExample">
<input type="button" onclick="google.script.run.serverFunc(this.parentNode)">
</form>
</body>
</html>
On the server, have your form handling function take one parameter - the form itself. The HTML form from the client code will be transformed into an equivalent JavaScript object where all named fields are string properties, except for files which will be blobs.
function doGet() {
return HtmlService.createHtmlOutputFromFile('myPage');
}
function serverFunc(theForm) {
var anExampleText = theForm.anExample; // This is a string
var fileBlob = theForm.theFile; // This is a Blob.
var adoc = DocsList.createFile(fileBlob);
return adoc.getUrl();
}
If you actually want to use that URL you are generating and returning, be sure to add a success handler to the google.script call. You can modify it like this:
// Defined somewhere before the form
function handler(url) {
// Do something with the url.
}
<input type="button" onclick=
"google.script.run.withSuccessHandler(handler).serverFunc(this.parentNode)">
try: return HtmlService.createTemplateFromFile('myPage').evaluate();
More: html service reference
I found an answer for my question.
Submit a Form using Google App Script's HtmlService
The code in the Google App Script link below is:
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Form.html');
template.action = ScriptApp.getService().getUrl();
return template.evaluate();
}
function doPost(e) {
var template = HtmlService.createTemplateFromFile('Thanks.html');
template.name = e.parameter.name;
template.comment = e.parameter.comment;
template.screenshot = e.parameter.screenshot;
return template.evaluate();
}
https://script.google.com/d/1i65oG_ymE1lreHtB6WBGaPHi3oLD_-wPd5Ter1nsN7maFAWgUA9DbE4C/edit
Thanks!