I've created a function in Google Script Editor that appends a row in Google Spreadsheet. Values being passed as parameters.
Now, what I want to do is, call this function in my HTML page (built using UI Services, not HTML Services) and pass the values to be stored from this page. I cannot find a way. Pls help?
At the time you asked this question, the documentation was not very rich. It has improved considerably, and there are examples provided that are close to what you want to do.
With the UI Service, the way you would accomplish this would be by using a handler function, either client-side or server-side, which would be triggered by a button click (for example), and handle the submission of a "form" (a set of input text areas, etc.). The handler would call your storage function, passing the values returned from the form.
See the examples in the documentation links provided above.
If your web app used Html Services, you would have several options for calling server-side apps-script, see Html Service: Communicate with Server Functions. There are also numerous questions here that demonstrate this:
Call a Google Apps Script function in HTML
HtmlService form submit opens new tab with foo bar URL
Short answer:
google.script.run.nameOfYourFunction();
Use this to call your function that is defined outside of the html file, from within the html file. Based on the docs
Related
I have a Google spreadsheet that has it's data loaded using a custom function.
The custom function calls a REST API, transforms the data and displays it.
The problem is that every time I open the doc, the function is called and all the REST API calls go out.
I need to be able to manually trigger service calls to refresh data, and in between show the data from last time.
How can I best achieve that?
Short answer
Instead of calling your function from a formula (custom function) call it from:
The script editor
A custom menu
Explanation
At this time custom functions are recalculated when the spreadsheet is open and when any of its arguments changes its values. To run the function at will use the script editor play or debug buttons or a custom menu. Also you could use other triggers. Choose the one that best suit your needs.
If you still want to cache the result of calling the corresponding REST API use the Class Cache.
References
Overview of Google Apps Script
Custom functions in Google Sheets
Cache Service
I have a Google Form and a script and a script bound to the form.
I'm trying to get a function to run when a user fill in the form.
But the only function I get to run is when a hook it to the OnFormSubmit trigger.
No other function is running, no matter what I try.
Can I run a function i Google App Script on initial load when a user is filling the form? Is this possible?
Thanks
More details (I'll accept some other way to accomplish the task):
the function should capture some url parameters I pass to the form, and send it over to Google Analytics... I believe that part is solved here: Google Forms & The Measurement Protocol
As the form has several pages, the parameters I pass to the first page gets lost when the user goes to next pages, so I cannot capture them when submitting the form - therefore I'm trying to do it whenever the users first edits the form.
I tried to add the params as prefilled fields on a hidden page, but if it is hidden then it too gets lost on submitting...
Since Sandy did not write out an answer, I will.
You cannot execute Apps Script as part of a form when the user visits it. You can't modify a form as the user is filling it out (Dynamic form...etc). If you need this type of behavior, you will need to create your own form as part of a Apps Script Web App.
Web App information: https://developers.google.com/apps-script/guides/web
Are there restrictions on what may be in an Apps Script library to be used by Google Spreadsheets? Specifically, can a library include an HTML dialog?
I've created a spreadsheet script that adds a menu item to present the user with a dialog box. It uses
HtmlService.createHtmlOutputFromFile('mappingForm').setSandboxMode(HtmlService.SandboxMode.IFRAME)
as described in https://developers.google.com/apps-script/guides/html/communication. The HTML file includes HTML, CSS and JavaScript with jQuery. It uses google.script.run to populate the dialog with data from the spreadsheet and to submit a form to it.
This all works fine in the original spreadsheet.
I need multiple spreadsheets to use this same code, however, so I'm trying to follow the general idea of Google Spreadsheet Scripts shared across spreadsheets (not libraries) to have a master script with a spreadsheet template and multiple copies.
I followed the directions at https://developers.google.com/apps-script/guide_libraries to create a library from the original spreadsheet. When another spreadsheet uses the library, I'm able to get the dialog to appear, but all calls back to the server (either to populate the dialog or to submit a form) fail with an error caught browser-side by the google.script.run.withFailureHandler as an Error object with properties:
message: "We're sorry, a server error occurred. Please wait a bit and try again."
name: "ScriptError"
I've placed Logger calls in the apps script to see if the server-side functions are being called but none of them are being hit. The script editor's Execution Transcript shows:
[14-12-27 19:38:05:340 PST] Starting execution
[14-12-27 19:38:05:372 PST] Execution failed: We're sorry, a server error occurred. Please wait a bit and try again. [0.0 seconds total runtime]
The client is making the call, but something is failing before it reaches the spreadsheet script.
This makes me wonder whether
I need to do something differently for the code to work as a library.
Libraries can't have dialogs.
There's a server bug.
Thanks in advance for any suggestions.
I was able to have a working library containing an HTML dialog by doing the following.
Move the script and HTML files from the original spreadsheet to a standalone script project. Take note of the library's Project key in the Info tab of File > Project properties.... It will be needed by any spreadsheet that intends to use the library.
If the standalone script project is to used by others, click its Share button to make it shareable to anyone with a link, otherwise it will silently fail for them.
If the HTML dialog needs to call back to a library function (to get or submit data), the library function must be present in the spreadsheet that uses the library, or you'll get an error message in the browser's JavaScript console.
In the spreadsheet that uses the library: Tools > Script editor... Click Resources > Libraries.... In the "Included Libraries" dialog box, enter the standalone project's key in the Find a Library text box, click Select, then choose the appropriate Version, change the Identifier, if necessary, and Save. The Identifier value creates an object of the same name for use by the spreadsheet's script to call library functions. In my case, it is SignupFormResponsesSheet.
In the same Script Editor's code editor, add wrapper functions that call library functions, including any that will be called back from the HTML dialog. My library has an onOpen() which creates two menu items to show HTML dialogs, so I added
function onOpen() {
SignupFormResponsesSheet.onOpen();
}
function showMappingForm() {
SignupFormResponsesSheet.showMappingForm();
}
function showSubmitForm() {
SignupFormResponsesSheet.showSubmitForm();
}
My HTML dialog has a number of callbacks to get and submit data, so rather than writing a wrapper function for each, I added one function to cover all of them by taking advantage of the way Apps Script treats a library as an object containing functions. The first argument is a string naming the library function to call. Any additional arguments are passed to the library function.
function runSignupFormResponseFunction(funcName, varargs) {
return SignupFormResponsesSheet[funcName].apply(this,
Array.prototype.slice.call(arguments, 1));
}
Because of the restriction identified in step 3 above, the JavaScript in the HTML dialog uses google.script.run to call the runSignupFormResponseFunction whenever it needs to get or submit data. For example, it has two lists that are dynamically populated with server data from the library's getRangeLabels and getColumnExamples functions (and one must be populated before the other), so the code is
google.script.run
.withFailureHandler(showError)
.withSuccessHandler(function(ranges) {
loadRanges(ranges);
// once ranges are loaded, load columns
google.script.run
.withSuccessHandler(loadColumns)
.withFailureHandler(showError)
.runSignupFormResponseFunction("getColumnExamples");
})
.runSignupFormResponseFunction("getRangeLabels");
This worked for me today. I hope it works for others who may find this question.
Here is what I'm trying to do:
Embed a Google spreadsheet in my website in multiple locations. For registered users, I want to show all the data in the spreadsheet. For unregistered users, I want to hide key numbers.
I have a spreadsheet with a custom function called blackOut(). I've put the blackOut function in all of the cells with sensitive data. All blackOut() need to do is this:
function blackOut(e) {
var is registered = ??
if (is_registered) return e;
else return "";
}
But I cant find any way to 'pass' any variables from my website to the function, so I haven't been able to make it work.
Here's my environment:
In PHP I'm using cURL to get the spreadsheet's embed code from this URL:
https://docs.google.com/spreadsheet/pub?key=[spreadsheet ID]&output=html&widget=true
then I'm doing a few str_replace functions to make the JS and CSS work.
Here's what I've tried:
using window.location in my function (doesn't work. Google doesn't let you access window)
passing a javascript variable in globally (in JS global variables are technically attached to the window object)
using SpreadsheetApp.getActiveSpreadsheet().getURL() (just returns the URL for the spreadsheet, not the one that existed in the http request)
looking through all of the available objects in Google Code
My Ideal Solution:
It would be great if I could just add '&blackout=true' to the URL, and pass that into blackOut() in the google script. I've looked around a lot, and I don't think it's possible.
I've looked at these links:
How can I get URL parameters passed to a Google Spreadsheet using Google Apps Script?
Alternative to global variables
GAS: Problems in using global variables in functions
Any ideas on how I can get this to work?
Maybe i'm understanding your question wrong, but am i to understand that you are not using a iframe or viewing the sheet directly? You are using a published url and from there you get your data. You already do some custom conversion to the HTML (so you have the knowledge and tools to edit your data/html yourself).
Could you go a small step further and create the whole html table yourself?
Then you could use the query functionality of google spreadsheets (url query parameters).
This way you could validate the users from your site and do two different data query's.
One with all the columns, one without some columns.
For example see: http://acrl.ala.org/techconnect/?p=4001
For the google language reference: https://developers.google.com/chart/interactive/docs/querylanguage
I need to generate/display an HTML page (or iframe or how-ever it could be done on demand from an apps script) from a Google sheet using Apps Scripts. It looks like there's an htmlForms service for Docs, but I can't find the equivalent for sheets.
My goal is to provide a menu item that can parse my data (already done) then call up another page where knockOutJs will be used to transfer the generated JSON into an html preview. Right now my script generates the JSON and if I could use something like
I'm using HtmlService.createHtmlOutputFromFile() to generate the HTML but FormApp.getUi() isn't valid in this context and neither is
You must get a reference to the current SpreadSheet (not the "ActiveSheet", but the entire SpreadSheet object) then call show() passing in your object from createHtmlOutputFromFile() or similar method.
var htmlRes HtmlService.createHtmlOutputFromFile('YourProjectHtmlFile');
SpreadsheetApp.getActiveSpreadsheet().show(htmlRes);