In an onOpen method, how can the document type be determined?
From the Quickstart: Add-on for Google Docs the following code is suggested:
function onOpen(e) {
DocumentApp.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi();
}
However, when a Google Sheet is opened the script throws an exception:
Exception: Cannot call DocumentApp.getUi() from this context. at onOpen(Code:9:15)
There should be a test, first, detecting the document type context that is being opened, allowing the script to select if and how it will add menu items. How to do that? The reference for onOpen indicates e.source will be a different type, but type of e.source
is only object
.
Desire is something like:
function onOpen(e) {
if (/* answer to this question: test if onOpen called for Doc only */) {
DocumentApp.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi();
}
}
If my understanding is correct, how about this answer? Please think of this as just one of several answers.
In this sample script, it retrieves the active document of the container-bound script when the Google Docs is opened. As the sample situation, when this script is used for the container-bound script of Spreadsheet, DocumentApp.getActiveDocument()
, SlidesApp.getActivePresentation()
and FormApp.getActiveForm()
return null
. And only SpreadsheetApp.getActiveSpreadsheet()
returns the object. This method uses this situation.
The sample script is as follows.
function onOpen() {
var docObject = DocumentApp.getActiveDocument() ? DocumentApp :
SpreadsheetApp.getActiveSpreadsheet() ? SpreadsheetApp :
SlidesApp.getActivePresentation() ? SlidesApp :
FormApp.getActiveForm() ? FormApp : null;
// When this is used for your script, it becomes as follows.
docObject.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi();
}
docObject
becomes the object of DocumentApp
. And docObject.getUi().createAddonMenu().addItem('Start', 'showSidebar').addToUi()
works for the Google Document.https://www.googleapis.com/auth/documents
https://www.googleapis.com/auth/forms
https://www.googleapis.com/auth/presentations
https://www.googleapis.com/auth/spreadsheets
FormApp.getActiveForm() ? FormApp :
.If I misunderstood your question and this was not the direction you want, I apologize.
At first, I apologize I misunderstood your goal. From your updated question, I could understand as follows.
If my understanding is correct, when the method of my answer is used, how about the following modification?
if (/* answer to this question: test if onOpen called for Doc only */) {
if (DocumentApp.getActiveDocument()) {
DocumentApp.getActiveDocument()
returns null
. By this, the script in the if statement is not run for Google Docs except for Google Document.Inbuilt global variable's .toString()
method usually gives the class name. You can use it to determine the document type.
function onOpen(e){
const app = this[ e.source + "App" ];//automatically becomes SpreadsheetApp or DocumentApp or any other editor App
app.getUi()/*Do whatever you want with the Ui object*/;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With