Pass webapp link parameter to html file in Google Apps Script - google-apps-script

I am trying to pass a parameter from a webapp link, so it can be used to pre-fill an html form (using HtmlService).
Apps Script -
function doGet(e) {
var formId = e.parameter.formId;
return HtmlService.createTemplateFromFile('Index')
.id = formId
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
}
Index.html -
<form id="myForm">
<input type="text" name="formId" value="<?=id?>"><br>
<input type="search" name="search">
</form>
Error received -
Cannot find function evaluate in object "xyz" (where xyz is the parameter included in the link).
I am not sure what I am doing wrong with the Apps Script code.
Many thanks in advance.
Happy coding!

var html = HtmlService.createTemplateFromFile('Index')
html.id = formId;
return html.evaluate()

Related

how to pass username and email from GAS to HTML form

im trying to pass username and email to the html form which is called in doGet.
function doGet(e) {
// e has url parameters which contain username and email
var id = e.parameter;
var name = e.postData.contents.split("&")[0];
// after a bunch of splitting ill have two vars
var name and var email, how do i pass this two vars to the index,
return HtmlService.createHtmlOutputFromFile('index').setSandboxMode(
HtmlService.SandboxMode.IFRAME);
}
this is index
<form id="uploaderForm">
<label for="uploaderForm">Upload plusieur fichiers</label>
<div>
//both inputs will be hidden, and will contain the values of name and email variables that i have in doGet
<input type="text" name="applicantName" id="applicantName"
placeholder="nom">
</div>
<div>
<input type="text" name="applicantEmail" id="applicantEmail"
placeholder="Email">
</div>
<div>
<input type="file" name="filesToUpload" id="filesToUpload" multiple>
<input type="button" value="Submit" onclick="uploadFiles()">
</div>
</form>
to sum up, i have two vars in doGet, var name and var email, i wanna pass them to the html index so i can use them as input values , so that the user doesnt have to manually type them
solution 1:
i havent completely tested this yet but im too excited, i spent two days on this i even had nightmares about it last night, so this is how i passed variables to the html form to use in the input
function doGet(e) {
var id = e.parameter;
var name = e.postData.contents.split("&")[0];
var email = e.postData.contents.split("&")[1];
var template = HtmlService.createTemplateFromFile('index');
template.myVar = name.split("=")[1];
template.email = email.split("=")[1];
return template.evaluate().setSandboxMode(
HtmlService.SandboxMode.IFRAME);
}
function doPost(e) {
return doGet(e);
}
and in the html , you can simply call the variables using or whatever you named it like so
<input type="text" name="applicantEmail" id="applicantEmail"
placeholder=<?= email ?> value=<?= email ?>>
the username and email are recieved from a local webpage form that has a post method, so generally im passing username and email to the GAS from my local web page , and then passing it to the html page of the GAS.
solution 2
if you are calling the google script app using and want to pass parameters or variables to the google app script, you can attach them to the URL in the iframe like so
<iframe src="https://script.google.com/.../exec?name=value1&email=value2...">
and then you can access name and email parameters in the google app script in the doGet function like so
function doGet(e) {
var name = e.parameter.name;
var email = e.parameter.email;
var template = HtmlService.createTemplateFromFile('index');
template.myVar = name;
template.email = email;
return template.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);

Creating a dialogue box to capture booking details in Google sheets App Script

I am using Google sheets with app script to build a reservations chart for a hotel
Can someone please tell me if there is a way to add a Dialogue box to a google sheet that can ask multiple questions? I have found the Prompt Dialogue box but that seems to allow only one text box for data entry. I have something like this
var result = ui.prompt(
"Let's get to know each other!",
"Please enter your name:",
ui.ButtonSet.OK_CANCEL
);
// Process the user's response.
var button = result.getSelectedButton();
var text = result.getResponseText();
if (button == ui.Button.OK) {
// User clicked "OK".
ui.alert("Your name is " + text + ".");
} else if (button == ui.Button.CANCEL) {
// User clicked "Cancel".
ui.alert("I didn't get your name.");
} else if (button == ui.Button.CLOSE) {
// User clicked X in the title bar.
ui.alert("You closed the dialog.");
}
If there isnt something pre-built, can you please recommend how else I can capture data which would then feed a second sheet within the same spreadsheet .
many thanks
You need to use the HTML service
The method you are using is quite limited. To go further than that you would need to create your own HTML file and serve it from Apps Script. The flow of that is:
Create an HTML file in the script editor
Create your HTML form
Write a script on the HTML that calls a function on your gs script.
Sample code
Code.gs
// Creates form on UI
function form() {
var htmlOutput = HtmlService
.createHtmlOutputFromFile('form')
.setWidth(250)
.setHeight(300);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Add your info');
}
// Uses info passed from rendered HTML to add data to sheet.
function addForm(data){
console.log(data)
SpreadsheetApp.getActiveSpreadsheet().getRange("A1:C1").setValues([data])
}
form.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
// function to run when server-side script is successful
function onSuccess(){
google.script.host.close()
}
// function to run when form is submitted
function sendForm(){
console.log("RUNNING")
let name = document.getElementById("name").value
let country = document.getElementById("country").value
let DOB = document.getElementById("DOB").value
let data = [name, country, DOB]
// call server side function
google.script.run.withSuccessHandler(onSuccess).addForm(data)
}
</script>
</head>
<body>
<form id="form" onsubmit="sendForm()">
<label for="name">First name:</label><br>
<input type="text" name="name" id="name">
<label for="country">Country:</label><br>
<input type="text" name="country" id="country">
<label for="DOB">DOB:</label><br>
<input type="text" name="DOB" id="DOB">
<input type="submit">
</form>
</body>
</html>
Explanation
When the function form() is run from the script editor, it displays your HTML in the Spreadsheet UI.
This shows a form with three text inputs and a submit button.
The submit button has a onsubmit="sendForm()" which is a function defined within the HTML.
It gets all the info from the form, and then calls google.script.run.withSuccessHandler(onSuccess).addForm(data). This is an asynchronous function that sends a request to the gs file to run the addForm function and then when successful, to run the onSuccess function in the HTML.
The onSuccess simply closes the form.
addForm adds the info to a range in the spreadsheet.
Reference
HTML service
Show Modal Dialog
google.script.run

HtmlService form submit opens new tab with foo bar URL

I am attempting to build a UI for a spreadsheet using GAS HtmlService. The HTML below is a very simple form with a single text box that pulls a value ("Kristina") from the sheet, successfully. However, when I try to submit the form a new tab is opened in Chrome that attempts to open the URL "bffc95ee-ff64-4d2c-xxxx-19d9824eb4b4.foo.bar/?fname=Kristina" with "xxxx" replacing more random letters and numbers (just in case). At no point do I use the words "foo.bar" in my code, so I'm pretty sure that that part isn't coming from me. It does not change each time or after logging out and back in. I'm getting the same result on two different computers.
<html>
<body>
<div>
<form id="formtest1">
<label>First Name</label>
<input name="fname" type="text" maxlength="255" value="<?= fname ?>"/>
<input type="submit" value="Submit"
onclick="google.script.run.processForm(document.getElementById('formtest1'));
google.script.host.close()"/>
</form>
</div>
</body>
</html>
The above is being displayed using the following function:
function htmltest(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sht = ss.getActiveSheet();
var html = HtmlService.createTemplateFromFile("HTML");
html.fname = sht.getRange(2, 3).getValue();
ss.show(html.evaluate());
};
If I understand correctly, the "google.script.run.processForm(...)" script in the HTML should trigger the following function, as set up in the projects triggers:
function onFormSubmit(){
Browser.msgBox("Test");
};
But it doesn't appear to do so as the form doesn't close and the msgBox doesn't appear. Only the foo bar URL in a new tab.
Hopefully I've explained the issue clearly and am not making an embarrassing mistake.
You cannot use a real "submit" button with google.script.run (this is a documented restriction in the user guide). Change it to "button" and it should work fine.
The project trigger onFormSubmit() will be triggered by a submission via the Forms Service. There is no relationship between this trigger and your HTML code; they are two different ways to interact with users.
An html forms pattern is shown in the HTML Service documentation here, and the script below is an adaptation of it.
Code.gs
The only real change from your original is that onFormSubmit() has been replaced with processForm(form), which includes a parameter, for the object that will be passed from the html code.
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "htmltest",
functionName : "htmltest"
}];
sheet.addMenu("Custom Menu", entries);
};
function htmltest(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sht = ss.getActiveSheet();
var html = HtmlService.createTemplateFromFile("HTML");
html.fname = sht.getRange(2, 3).getValue();
//Logger.log( html.getCodeWithComments() );
ss.show(html.evaluate());
};
function processForm(form){
var fname = form.fname;
Browser.msgBox("Test - " + fname);
};
HTML.html
This is a modification of your original, echoing the pattern from the documentation. The form submission SuccessHandler is a one-liner, which closes the dialog. Once it completes, the server-side function is invoked with the form content, retrieved using this.parentNode (to refer to the form).
There are other ways - see Get value of html text box in Apps Script function for a different approach.
<html>
<script type="text/javascript">
// SuccessHandler to close form
function close() {google.script.host.close();}
</script>
<body>
<div>
<form>
<label>First Name</label>
<input name="fname" type="text" maxlength="255" value="<?= fname ?>"/>
<input type="button" value="Submit" onclick="google.script.run
.withSuccessHandler(close)
.processForm(this.parentNode)"/>
</form>
</div>
</body>
</html>
Just add this to your script tag on your html file.
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
Source: HTML Service: Communicate with Server Functions

form htmlservice issue with passing parameters

I have looked at other posts and am struggling with the same issue of how to pass form values to GAS. Since GUI editor has been depreciated, I decided to go the htmlservice form route. In this simple code below, I'm just trying to access the form field aField and paste it in a cell.
function doGet() {
return HtmlService.createHtmlOutputFromFile('myForm.html');
}
function processForm(value) {
var myRange = SpreadsheetApp.openById("xxx").getSheetByName("Results-List").getDataRange("B20");
myRange.setValue(value.aField);
}
This is the HTML template myForm.html:
<html>
<form id="myForm">
<input name="aField" id="aField">
<input type="button" id="submit" value="submit" onclick = "sendData()">
</form>
<script>
function sendData() {
google.script.run.processForm(document.getElementById("myForm"));
}
</script>
</html>
.getDataRange() has a different use. Use .getRange('B20') to get this to work.

Accessing object is Google App Script

I am actually following the HtmlService documentation (https://developers.google.com/apps-script/html_service) in creating a form. I notice there is this part where it says it will be an object after user submit the form and the structure will be like this:
{ myFile: <a Blob containing the file>;
aField: <the value in the field> }
Can I know how can I access to those object in Google App Script?
In your server code:
function processForm(theForm) {
Logger.log(theForm.aField);
Logger.log(theForm.myFile.getName());
}
In your HTML:
<form id='myForm'>
<input name='myFile' type='file'>
<input name='aField'>
</form>
<script>
google.script.run.processForm(document.getElementById('myForm'));
</script>