Modifying an existing Calendar Event from HtmlService input - html

I'm trying to add a "Sign Up" link to a Google Calendar Event where upon clicking the user is prompted via HtmlService to submit their email address. Their email address is then added to the event.
Here's a similar example. What I'd like to do differently is use HtmlService to have the user input their email address, which then is passed back to GAS to be added to the Calendar Event in question. That way they can choose the email they want (instead of whatever Session.getActiveUser().getEmail() returns) to sign up with. (and by sign up, I mean get added to the guest list - they still have to accept the invite, but that's fine).
Is this possible? I'm not seeing any examples of this so maybe there's a better way?
I am starting to tear out what little hair I have. I've included my latest sample code, where I pass the event object into the HTML template. It's not throwing an error, but it's not working either. Thank you in advance!!
Code.gs:
function doGet(event) {
// // shorten the event parameter path;
var param = event.parameter;
// // get the calendar event id passed in the query parameter
var eventId = param.eId;
var calId = param.calId;
var cal = CalendarApp.getCalendarById(calId);
var t = HtmlService.createTemplateFromFile('Index');
t.eObj = cal.getEventById(eventId);
return t.evaluate();
}
function addEmail(emObj,myForm){
var guestEmail = myForm.user;
emObj.addGuest(guestEmail)
}
and Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function update() {
alert("Success!");
}
</script>
</head>
<body>
<form id="myForm">
<input id="userEmail" name="user" type="text" />
<input type="button" value="Submit" onClick="google.script.run.withSuccessHandler(update).addEmail(eObj,this.form)" />
</form>
</body>
</html>

You don't have scriptlets in your html file, so you don't need to evaluate a template. I've added another 2 input fields for the calId and eventId. They get replaced in the HTML before being served. Then the event ID and Cal ID are passed back in the form object.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function update() {
alert("Success!");
}
</script>
</head>
<body>
<form id="myForm">
<input id="userEmail" name="user" type="text" />
<input name="calId" type="text" style="display:none"
value="zzz_calID_zzz"/>
<input name="eventId" type="text" style="display:none"
value="zzz_eventID_zzz"/>
<input type="button" value="Submit" onClick="google.script.run
.withSuccessHandler(update)
.addEmail(this.form)" />
</form>
</body>
</html>
doGet:
function doGet(event) {
// // shorten the event parameter path;
var param = event.parameter;
// // get the calendar event id passed in the query parameter
var eventId = param.eId;
var calId = param.calId;
var t = HtmlService.createHtmlOutputFromFile('Index').getContent();
t = t.replace('zzz_calID_zzz',calId);
t = t.replace('zzz_eventID_zzz',eventID);
return HtmlService.createHtmlOutput(t);
}
Server code:
function addEmail(myForm){
var cal = CalendarApp.getCalendarById(myForm.calId);
var event = cal.getEventById(myForm.eventId);
var guestEmail = myForm.user;
event.addGuest(guestEmail)
}

Related

Uploading An Image With Google Apps Script To A GSheet - Passing Values To And From HTML Service Modal Dialog

I'm trying to trigger a file upload off of a Google Sheet, taking the uploaded file, add it to a Google Drive folder, and then return the URL of the uploaded file and place it in a cell on the Sheet. I'm currently triggering the file upload by using a checkbox. Once you set the checkbox to TRUE, it'll pop up a dialog box with a file upload input field. This is triggered by an installed onEdit function. Also, info on the row in the sheet will be used to name the newly uploaded file. This info will be input manually on the sheet.
I get to the showModalDialog line, and the dialog box comes up just fine, but I can't figure out how to pass variables from the original function to the HTML service and then back again (with the file) to upload to Drive, set the name, and put the URL back on the sheet.
Here's the first function in Code.gs, receiving values from the onEdit function:
function addFile(ss,ui,row,total) { \\Triggered if edited cell is in column 25 & value is TRUE
Logger.log('add file function');
var name = ss.getRange(row,1).getDisplayValue();
var date = ss.getRange(row,3).getDisplayValue();
var filename = 'Row ' + row + ' - ' + name + ' - ' + date + ' - ' + total;
var htmlTemp = HtmlService.createTemplateFromFile('Index');
htmlTemp.fName = filename;
htmlTemp.position = row;
var html = htmlTemp.evaluate().setHeight(76).setWidth(415);
ui.showModalDialog(html, 'Upload');
Logger.log('end of add file function');
}
And here's what's in Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_center">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<form>
Please upload image below.<br /><br />
<input type="file" name="upload" id="file" accept="image/*,.pdf" />
<input type="button" value="Submit" class="action" onclick="formData(this.parentNode)" />
<input type="button" value="Close" onclick="google.script.host.close()" />
</form>
<script>
function formData(obj){
var newFileName = <? fName ?>;
var rowNum = <? position ?>;
google.script.run.withSuccessHandler(closeIt).upload(obj,newFileName,rowNum);
}
function closeIt(e){
console.log(e);
google.script.host.close();
};
</script>
</body>
</html>
And here's the return function on Code.gs:
function upload(obj,newFileName,rowNum) {
Logger.log('upload function');
var upFile = DriveApp.getFolderById('[folderid]').createFile(obj).setName(newFileName);
var fileUrl = upFile.getUrl();
Logger.log(fileUrl);
var urlCell = SpreadsheetApp.getSheetByName('sheet name').getRange(rowNum,26);
urlCell.setValue('=HYPERLINK("' + fileUrl + '","View image")');
}
Running this code, the dialog box comes up just fine, and I'm able to select a file for upload. However, clicking the Submit button does nothing, and the box stays up until I X it out or hit the Cancel button. The logs only get so far as 'end of add file function' and never gets to the upload function. Should the google.script.run.withSuccessHandler line close the dialog box, or is something else needed to confirm / get the file and close the box?
I've been searching online and have found a number of posts relating to this, but none seem to address this specific issue. This is also pretty much a frankenstein of code I've cobbled together from those posts, so it's possible there's just something that doesn't belong in there and if that is the case I do apologize. Any help would be appreciated; thanks!
[Edit: the submit button wasn't opening a separate tab because I was using <input type="button"> instead of <button>.]
According to the documentation [1] in the “Parameters and return values” part,
if you’re going to send the form object as a parameter “it must be the function’s only parameter”. So you should send the parameters inside the form, using inputs of types “hidden” or “text”, then, from code.gs you can retrieve the input data of the Form object.
Another thing stated in the documentation [1] in the “form” section, is that you need to disable the default submit action with preventFormSubmit function.
Another problem is that the correct way of printing the variables passed to the template are using <?= ?> instead of <? ?> which works to execute code but not to print variables. [2]
Your “addFile” function is all right. Below is the code i've tested on my environment and I was able to upload an image successfully and print the url in the sheet.
Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_center">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
</head>
<body>
<form id="myForm">
Please upload image below.<br /><br />
<input type="hidden" name="fname" id="fname" value="<?= fName ?>"/>
<input type="hidden" name="position" id="position" value="<?= position ?>"/>
<input type="file" name="file" id="file" accept="image/jpeg,.pdf" />
<input type="button" value="Submit" class="action" onclick="formData(this.parentNode)" />
<input type="button" value="Close" onclick="google.script.host.close()" />
</form>
<script>
//Disable the default submit action using “func1”
window.onload=func1;
function func1() {
document.getElementById('myForm').addEventListener('submit', function(event) {
event.preventDefault();
});
}
function formData(obj){
google.script.run.withSuccessHandler(closeIt).upload(obj);
}
function closeIt(e){
console.log(e);
google.script.host.close();
};
</script>
</body>
</html>
Code.gs (upload function):
function upload(obj) {
//Retrieve the input data of the Form object.
var newFileName = obj.fname;
var rowNum = obj.position;
var blob = obj.file;
var upFile = DriveApp.getFolderById('[folderid]').createFile(blob).setName(newFileName);
var fileUrl = upFile.getUrl();
var urlCell = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1').getRange(rowNum,5);
urlCell.setValue('=HYPERLINK("' + fileUrl + '","View image")');
}
[1] https://developers.google.com/apps-script/guides/html/communication
[2] https://developers.google.com/apps-script/guides/html/templates

How to get input information on web app like msg box using google script

I need output on web app which key information in input box. using html and java script I deployed as web app. once key the information I should get pop up msg on web app that information. Please help me out of this problem.
I have created HTML and javascript, using that data is getting capture in google spreadsheet but that information I should get on web app like pop up msg
Key information get in pop up msg in web app only
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>US P2P Standard Notes</h2>
<label>G-case #: </label><input type= "#" id="username">
<button id="btn">Pass</button> <form action="">
<p> </p>
</form>
<script>
document.getElementById("btn").addEventListener("click",doStuff);
function doStuff(){
var uname = document.getElementById("username").value;
google.script.run.userClicked(uname);
document.getElementById("username").value ="";
}
</script>
</body>
</html>
function doGet() {
return HtmlService.createHtmlOutputFromFile("page");
}
function userClicked(name){
var url = "docs.google.com/spreadsheets/d/…";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
ws.appendRow([name + "This is G-case#"]);
}
Try this:
I have it running as a dialog. I assume that you can take it from here and turn it into a Web App.
The html file was name aq4.html:
<html>
<head>
<base target="_top">
</head>
<body>
<h2>US P2P Standard Notes</h2>
<label>G-case #: </label><input type="text" id="username" />
<input type="button" id="btn" value="Pass" onClick="doStuff();" />
<script>
function doStuff(){
var uname=document.getElementById("username").value;
google.script.run
.withSuccessHandler(function(){
document.getElementById("username").value ="";
})
.userClicked(uname);
}
</script>
</body>
</html>
Since there was nothing in your form, I removed it. I also changed your button style to the input version. I added a withSuccessHandler to remove the entered text.
This is the google script:
function userClicked(name){
var ss=SpreadsheetApp.getActive();
var ws=ss.getSheetByName("Sheet1");
ws.appendRow([name + "This is G-case#"]);
return;
}
function showDialog() {
var userInterface=HtmlService.createHtmlOutputFromFile('aq4');
SpreadsheetApp.getUi().showModelessDialog(userInterface, "My Page")
}
Your saying something about a pop up but I haven't a clue as to what you're trying to say. Perhaps, you can elaborate on that a bit.
Oh and this is what the current dialog looks like:

Control Flow Between Server and Client and Back to Server for Google Apps Script

I have a question about the control flow between some JavaScript code running as bound functions within a google spreadsheet - so server side - and a dialog (that happens to be Modal, but Modeless is the same) that is client side.
While the code examples below work fine in that the dialog successfully calls the server side function as per the line below, and the withSuccessHandler works too.
google.script.run.withSuccessHandler(success_callback).getCredentials(this.parentNode)
But what I actually want to achieve is for some server side code to carry on executing once the dialog has gone; ideally from the point the .showModalDialog() function was called, but I'd be happy just passing control back to any server-side function.
Some example software is below; don't forget this works, just not how I want it too! Essentially the event handler for a menu item created by the the OnOpen() function calls a modal dialog to prompt the user for security credentials.
var html = HtmlService.createHtmlOutputFromFile('authorization_dialog');
SpreadsheetApp.getUi()
.showModalDialog(html, 'Authorization Dialog');
The HTML file:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form>
Authorization Code:
<input type="text" name="authorization_code"><br><br>
Account ID:
<input type="text" name="account_id"><br><br>
Enter account details...
<br>
<br><br>
<input type="button" value="OK"
onclick="google.script.run.withSuccessHandler(success_callback).getCredentials(this.parentNode)" />
<input type="button" value="Close"
onclick="google.script.host.close()" />
</form>
<script>
// Using this call back prevents the need to hit the Close Button after OK.
function success_callback() {
google.script.host.close(); // Close the dialog.
}
</script>
</body>
</html>
If you don't need a response from the server-side function, simply omit 'withSuccessHandler';
function func_client(){
google.script.run.func_server();
google.script.host.close();
}
In this case, the server-side code will continue executing without locking your client's UI - you can call any other functions inside 'func_server'.
If you'd like to process a response from the first function call, call the second function from 'success_callback'. The dialog will be closed without waiting for the google.script.run to complete, but the server code will continue executing.
In the example below, the 1st server function passes form data back to the client where 'success_callback' immediately invokes another server function that takes a while to complete (it logs each file in my Google Drive);
Client:
<form id="form">
.....
<input type="submit" id="ok" value="OK" />
<input type="button" value="Close" onclick="google.script.host.close()" />
.....
</form>
<script>
window.onload = function(){
document.getElementById("form")
.addEventListener("submit", function(e){
e.preventDefault();
google.script.run
.withSuccessHandler(success_callback)
.logFormData(this);
});
}
function success_callback(response) {
console.log(response);
google.script.run.scanFiles();
google.script.host.close(); // Close the dialog.
}
</script>
Server:
function showDialog(){
var ui = SpreadsheetApp.getUi();
//IMPORTANT: client-side scripts won't be executed
//without calling evaluate() on the HtmlTemplate object before passing it to UI;
var template = HtmlService.createTemplateFromFile("dialog");
var html = template.evaluate();
ui.showModalDialog(html, "dialog");
}
function logFormData(formData){
return formData;
}
function scanFiles() {
var files = DriveApp.getFiles();
var file;
while (files.hasNext()) {
file = files.next();
Logger.log(file.getName() + ": " + file.getMimeType());
}
}

Convert web document objects to a Spreadsheet function

Using and spreadsheet, I have an HTML web that fills some text boxes and create some google charts when a csv file is dropped (this is not a Form)
I need to make a function that let me parse the value of the text boxes in order to fill a spreadsheet, this is my code so far:
Tablas.html (I am trying to pass all the document object as a parameter)
<input id="cmd" onclick="formSubmit()" type="button" value="Descargar SnapShot">
<script type="text/javascript">
function formSubmit() {
google.script.run.getValuesFromForm(document);
}
And the gs Script: (With the document as a parameter, i am trying to recover a text box named "modequ" to fill a new row in the Spreadsheet)
function getValuesFromForm(document){
var ssID = "12GvIStMKqmRFNBM-C67NCDeb89-c55K7KQtcuEYmJWQ",
sheet = SpreadsheetApp.openById(ssID).getSheets()[0],
modequ = document.getElementById("modequ").value;
sheet.appendRow([modequ]);
}
Is there any way to connect the all the document objects in the page made with the spreadsheet so i can append and process it? I though if maybe if i pass the all the document object this would be possible.
Regards
The document.getElementById() method returns a reference from the id attribute from your HTML, it needs to be inside your formSubmit() function:
function formSubmit() {
var modequ = document.getElementById('modequ').value;
google.script.run.getValuesFromForm(modequ);
}
This way you can get all the values individually and then pass them as parameter e.g. google.script.run.getValuesFromForm(modequ, tipmoto, smr)
However, if you want to pass all the form elements and then get them by name, you can do something like this:
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="form" name="form">
<input name="modequ" type="text">
<input name="tipmoto" type="text">
<input name="series" type="text">
<input id="cmd" onclick="formSubmit()" type="button" value="Descargar SnapShot">
</form>
</body>
</html>
<script type="text/javascript">
function formSubmit(){
google.script.run.getValuesFromForm(document.forms[0]);
}
</script>
GS:
function getValuesFromForm(res){
var ssID = '12GvIStMKqmRFNBM-C67NCDeb89-c55K7KQtcuEYmJWQ',
sheet = SpreadsheetApp.openById(ssID).getSheets()[0];
sheet.appendRow([res.modequ, res.tipmoto, res.series]);
}

create a new row in google spreadsheet from an html form

I am medical researcher, and I am creating a database of my patients, I have a form in html and want the variables obtained were stored in a spreadsheet of google, so far I have only this:
spreadsheet:
my spreadsheet in google
code.gs:
function addProduct() {
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow(['name', 'age']);
}
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index.html')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Name and age!
<input type=text name=name id=name>
<input type=number name=age id=age>
<input type=submit onclick=google.script.run.addProduct()>
</body>
</html>
I dont know how to link the variables in the html form, to the code.gs to enter the answers in a new row with the sheet.appendRow
I will appreciate your help,
thanks
Your input tags are not in a form, so you can't get the form element as a whole. Which you don't need to do, but it's worth mentioning because there are multiple ways you can structure things.
You can use what's called the DOM to get the values out of the input tags.
<body>
Name and age!
<input type=text name=name id=name>
<input type=number name=age id=age>
<input type=submit onclick="myClientSideJavaScriptFunction()">
</body>
<script>
function myClientSideJavaScriptFunction() {
var inputOneValue = document.getElementById('name').value;
var inputTwoValue = document.getElementById('age').value;
google.script.run
.addProduct(inputOneValue, inputTwoValue);
};
</script>
Code.gs
function addProduct(x1, anythingYouWantToNameIt) {
var myArray = [];
myArray.push(x1);
myArray.push(anythingYouWantToNameIt);
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow(myArray);
};