custom menu on google spreadsheet - google-apps-script

Need expert help, can we run function directly from the menu, instead of Sub-menu, it fails double clicking.
and I would want to close the dialog box after the download start, and can we delete the sheet after we download it ? :
SpreadsheetApp.getActive().deleteSheet(.getSheetId(sID));
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('Download')
.addItem('Download', 'Download')
.addToUi();
}
function Download() {
var ssID = SpreadsheetApp.getActive().getId();
var sID = SpreadsheetApp.getActive().getSheetId();
var URL = 'https://docs.google.com/spreadsheets/d/'+ssID+'/export?format=pdf&gid='+sID;
var htmlOutput = HtmlService
.createHtmlOutput('Click to download')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(160)
.setHeight(60);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Download');
}

If you mean the very top level menu, then the answer would be no.
You can delete a sheet but you will have to put a spreadsheet into the trash first. Although I think it's possible for GSuite Admins to get file delete authorization. I don't know I never bothered with it.
You can close the dialog box with google.script.host.close() Reference
Click Me

Related

Google Docs Apps Script Loading Indicator

I'm running a script when I open/refresh a Google Doc. It takes some time to run and can affect values in the doc, so I want to show some type of loading indicator to the user until it's done. I would prefer to not overlay a modal, so the doc is still accessible, but apart from that any solution, even a hacky one, would be ok.
// EXECUTE SCRIPT ON OPEN
function onOpen() {
// SHOW LOADING TO USER
initializeDoc();
doSomeStuffThatTakesSomeTime();
const ui = DocumentApp.getUi();
ui.createMenu('MyMenu')
.addItem('Click', 'doSomeStuffThatTakesSomeTime')
.addToUi();
// TURN LOADING OFF
}
Loading...
function loading() {
const ui = DocumentApp.getUi();
ui.showModelessDialog(HtmlService.createHtmlOutput("Loading...."),"Please Wait");
Utilities.sleep(5000);
const hl = '<!DOCTYPE html><html><head><base target="_top"></head><script>window.onload=()=>{google.script.host.close();}</script><body></body></html>';
ui.showModelessDialog(HtmlService.createHtmlOutput(hl),"Good Bye")
}
You will require an installable onOpen() such as below:
function onMyOpen(e) {
loading();
}

Is there a way to put chart created in google apps script in a tab on google sheet?

I am new to google apps scripts and coding but I created a Sankey diagram in google apps script using the google visualization HTML code. I am using the data from a google sheet because it is dynamic data. Currently I successfully deployed the diagram as a web app that updates when refreshed. However, I am wondering if it's possible to put the sheet IN the google sheet - maybe as a separate tab? I want to be able to share the google sheet and have the data and Sankey diagram immediately available.
Here is my code for grabbing the spreadsheet data and publishing it as a web app:
function doGet(e) {
return HtmlService
.createTemplateFromFile("Index")
.evaluate()
.setTitle("Google Spreadsheet Chart")
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function getSpreadsheetData() {
var ssID = "XXXXXXXXXXXXXXX",
sheet = SpreadsheetApp.openById(ssID).getSheets()[0],
data = sheet.getDataRange().getValues();
return data;
}
This is for many people to view so I had an alert pop up onOpen that says "Look at the diagram menu" and then a menu pop up onOpen to click on the diagram.
function onOpen() {
alert();
menu();
getSpreadsheetData();
openDiagram();
}
function alert() {
var ui = SpreadsheetApp.getUi();
ui.alert('To see diagrams for different brands, click on the "Diagram" menu.');
}
function menu() {
SpreadsheetApp.getUi()
.createMenu('Diagram')
.addItem('Diagram', 'openDiagram')
.addToUi();
}
function getSpreadsheetData() {
var
sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data'),
data = sheet.getDataRange().getValues();
return data;
}
function openDiagram() {
var html = HtmlService.createHtmlOutputFromFile('Index')
.setWidth(1000)
.setHeight(800);
SpreadsheetApp.getUi()
.showModalDialog(html, 'Diagram');
}
Then when I click on the diagram under the menu a window opens with my diagram.

onOpen event does not not launch a dialog box

I have a sheet that I send out to staff (copies that are shared) but when I copy this the function onOpen does not launch the dialog box.
function onOpen() {
SpreadsheetApp.getUi()
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('Index');
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Math Sheet Directions');
}
Take a deep look on the next thread : onOpen not executing?
As you can see from the thread and Issue Tracker:
Google has restriction for onOpen functionality
Is there a different way to achieve your goal?
You can create a red button "Show URLs" and assign it a function.
For example:
function openDialogBox() {
// your html content here
var html = "<a href='https://google.com'>Google.com</a><br /><a href='https://stackoverflow.com'>Stackoverflow.com</a>" ;
var htmlOutput = HtmlService
.createHtmlOutput(html)
.setWidth(250)
.setHeight(300);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'URL links');
}
This is how it looks like:
We don't have any restriction here.
I know this method doesn't help you, but probably this is the only way to achieve similar behavior of what you want to do :)
Reference
Google Apps Script - onOpen()
Google Apps Script - Class HtmlService
Google Apps Script Guide - HTML Service: Create and Serve HTML

Show an alert dialog/pup-up visible to all users in a Google Spreedsheet

I have Google spreadsheet that it's edited with "Anyone with the link can edit" rights, by multiple people (8-10) at the same time. I am the owner and maintainer of that file and occasionally i want to show an alert dialog with a message to all active users in the file. To do that i am using the following code:
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show alert', 'showAlert')
.addToUi();
}
function showAlert() {
var ui = SpreadsheetApp.getUi(); // Same variations.
var result = ui.alert(
'ATTENTION!',
'MY ATTENTION MESSAGE...BLA...BLA...BLA.',
ui.ButtonSet.OK);
}
Everything working fine, the alert dialog shows up properly but.... it's visible only to me. No one of the active users in the spreadsheet sees it.
I've try several code alternatives with no luck and also because i read in some sites that only people with "editor" role can see these dialogs, i've try to add the users of the spreadsheet as editors with this code:
Drive.Permissions.insert(
{
'role': 'editor',
'type': 'user',
'value': 'usermail#examplemail.com'
},
fileId,
{
'sendNotificationEmails': 'false'
});
Again... no luck!!!.
What am i doing wrong here ?. How can make this work and be able to sent an alert dialog to all types/roles of users in my spreadsheet?
Google Sheets / Google Apps Script doesn't include a feature to show an alert / dialog to all the users viewing the spreadsheet and can't make a sheet (tab) as the active tab for all users viewing the spreadsheet either.
You could email, Google Hangouts, Google Hangouts Chat or another similar app to send them an alert.
you don't need a menu, just a ui.
I have a similar sheet and use this code.
function onOpen() {
var SS = SpreadsheetApp.getActiveSpreadsheet();
var ui = SpreadsheetApp.getUi();
ui.alert("Greetings! Message here.\n Thanks.");
}

Authorization Lifecycle on published add-on is not working

Have a problem with my add-on that should, but not creating a menu items in Add-ons on Google Sheets and Docs on install from the store until the page is refreshed.
According to Google Support I should look in to the following:
"Usually this is caused by a problem with the Authorization Lifecycle, specifically the opening stage.
The most common culprit is a global variable in the code that tries to access Google services without authorization, like:
var doc = DocumentApp.getActiveDocument();
See the documentation:
Warning: When your onOpen(e) function runs, the entire script is loaded and any global statements are executed. These statements execute under the same authorization mode as onOpen(e) and will fail if the mode prohibits them. This preventsonOpen(e) from running. If your published add-on fails to add its menu items, look in the browser's JavaScript console to see if an error was thrown, then examine your script to see whether the onOpen(e) function or global variables call services that aren't allowed in AuthMode.NONE."
I have no idea what and how should I deal with this as my add-on was not created by me. I can do minor things, but this is something that I cannot handle on my own and really need your help please.
Hear is my script:
function onOpen(e) {
SpreadsheetApp.getUi().createAddonMenu()
.addItem('Browse Templates', 'browseTemplates')
.addToUi();
}
function onInstall(e) {
onOpen(e);
}
function browseTemplates(){
collectBasicData();
// Display a modal dialog box with custom HtmlService content.
var htmlOutput = HtmlService
.createTemplateFromFile("Gallery").evaluate()
.setWidth(700)
.setHeight(510);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Spreadsheet123 - Template Vault');
}
function collectAllData(){
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(DATA_SHEET);
DATA = sheet.getDataRange().getValues();
return DATA;
}
function collectBasicData(){
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(PIVOT_SHEET);
var tabSheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(TAB_SHEET);
BASIC_DATA = {
"tab_about" : getValue(tabSheet,"B1"),
"tab_help": getValue(tabSheet,"B2"),
"pivot":sheet.getDataRange().getValues()
};
return false;
}
function getValue(sheet,addr){
return sheet.getRange(addr).getValue().toString().replace(/^\s+|\s+$/g, '');
}
function createACopy(id){
var docName = DocsList.getFileById(id).getName();
return DocsList.getFileById(id).makeCopy(docName).getUrl();
}
function insertInCurrent(id){
var destinationSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheets = SpreadsheetApp.openById(id).getSheets();
for(var i=0;i<sourceSheets.length;i++){
var sheetName = sourceSheets[i].getName();
var source = SpreadsheetApp.openById(id).getSheetByName(sheetName);
source.copyTo(destinationSpreadSheet).setName(sheetName);
}
}
I have looked in to the documentation on Google, but cannot understand how and where I should use it in my script.
Your help is highly appreciated and thanks in advance