Reputation: 203
I have a Google Sheet that runs some Apps Script server code to connect to an SQL server. I want to show the message "loading..." in the modal dialog while data is being refreshed. I can get the modal to pop up, but I want to auto-close the dialog as soon as the code is finished.
An example I have set up is:
function testpop () {
var htmlOutput = HtmlService
.createHtmlOutput('<p> This box will close when the data has finished loading.</p>')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(250)
.setHeight(200);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Loading...');
sleep(1000);
//close the dialog
}
I know this can be called on a client side but need it to be handled in the GS so it fires when the code is done.
Upvotes: 18
Views: 17904
Reputation: 93
This solution provides a button to close the dialog immediately and will close automatically after 5000 milliseconds (5 sec.) by using "onload="setTimeout(closer, 5000)" in the body tag. It will pass a google script variable to the HTML to customize the dialog box.
Here's what I came up with...
My GS File:
function myGSFunction(inputVariable){
const ui = SpreadsheetApp.getUi();
let gsVariable = inputVariable.toUpperCase().trim() || null;
let htmlOutput;
.
.
.
htmlOutput = HtmlService.createTemplateFromFile('errorModelessDialog');
htmlOutput.htmlVariable = gsVariable; //define variable accessible in html
ui.showModelessDialog(htmlOutput.evaluate().setWidth(400).setHeight(150), 'ERROR');
.
.
.
};
My errorModelessDialog.html File:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body onload="setTimeout(closer, 5000)">
<p align="center"><?!=htmlVariable?> is not valid.</p>
<p align="center"><button onclick="google.script.host.close()">Close</button></p>
<script>
function closer(){
google.script.host.close();
}
</script>
</body>
</html>
Upvotes: 0
Reputation: 53
I too went with the answer given by @pcw11211. I dressed it up a little by encapsulating the htmlmodalDialog call in a function that can either open or close a dialog. I added a little html styling in there too. Also note the try/catch around the htmlmodalDialog that is there so that the scrip can still run when you are testing from the script editor, otherwise the main script is sometimes(?) halted with a Context error.
/**
* HELPER FUNCTION : TO OPEN & CLOSE MODAL DIALOGUE
*/
function htmlmodalDialog(title, text, close){
var htmlText = '<div>' + text + '</div>';
htmlText += '<style type="text/css">';
htmlText += 'body{text-align: center; font-family: Roboto, Arial, sans-serif; font-size: 14px;}';
htmlText += 'div{margin: auto;}';
htmlText += '</style>';
if(close){htmlText += '<script>google.script.host.close();</script>';}
var htmlOutput = HtmlService
.createHtmlOutput(htmlText)
.setHeight(60)
.setWidth(200);
try {
SpreadsheetApp.getUi().showModalDialog(htmlOutput, title);
}catch(e){
Logger.log('function htmlmodalDialog(title, text, close)');
Logger.log(e);
}
}
The function is called from the main code as follows with the last argument being an open/close boolean.
htmlmodalDialog('Starting', 'Working ...', false);
//do something here
htmlmodalDialog('Finished', 'Operation completed.', true);
Hope this helps somebody.
Upvotes: 1
Reputation: 261
//show dialog
var output = HtmlService.createHtmlOutput('<b>Please wait...</b>');
SpreadsheetApp.getUi().showModalDialog(output, 'Saving...');
some code
//close dialog
var output = HtmlService.createHtmlOutput('<script>google.script.host.close();</script>');
SpreadsheetApp.getUi().showModalDialog(output, 'Loading...');
*optional
ui.alert("Saved Successfully!")
Upvotes: 20
Reputation: 31300
The flow of events could be:
onLoad
event of modal dialog triggers client side codegoogle.script.run
triggers a server side .gs
function to run.gs
script file runs.google.script.host.close();
You'll need a <script>
tag in your modal dialog.
<script>
window.onload = function() {
//console.log('window.onload ran!');
google.script.run
.withSuccessHandler(closeDialog)
.theFunctionNameToUpdateDatabase()
};
window.closeDialog = function() {
google.script.host.close();
};
</script>
Right now you are using:
HtmlService.createHtmlOutput(the HTML here)
You could create the HTML from a file instead:
HtmlService.createHtmlOutputFromFile(filename)
Upvotes: 20