I have a very simple Google Apps Script which uses showModalDialog()
to open an HTML form over a spreadsheet. The popup tries to send an input value back to the sheet and then close itself. The problem is sometimes the popup's POST request (called using google.script.run()
) is cancelled and the sheet is not updated.
When I remove the call to google.script.host.close()
the request completes successfully and the sheet is updated. EDIT: Arrgh, I swear this used to work, but now I can't get the data written back to the sheet under any circumstances. Removing the close()
does allow the callback to be sent successfully, though.
I've tried using async/await or a success handler (see bottom of question) but neither have worked. How do I make the popup self-closing after the data is successfully sent?
Here's the server-side code:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Test Menu')
.addItem('Open Test Popup', 'showPopup')
.addToUi();
return false;
}
function showPopup(){
var html = HtmlService.createTemplateFromFile('Popup').evaluate().setWidth(400).setHeight(350);
SpreadsheetApp.getUi().showModalDialog(html, 'Test Title');
return false;
}
function writeCustomValue(valueToWrite) {
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var cell = sheet.getCurrentCell();
cell.setValue(valueToWrite);
return false;
}
Here's the popup client-side code:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<div class="block form-group">
<label for="valueToWrite">Write this value</label>
<input type="text" id="valueToWrite">
</div>
<button id="writeResponse" onclick='writeResponse()' class="action block">Write this value</button>
<script>
function writeResponse(){
document.getElementById('writeResponse').innerHTML = 'Saving ...';
document.getElementById('writeResponse').disabled = true;
//Get the value of the input field
var valueToWrite = document.getElementById('valueToWrite').value;
//Send the value of the text field as an argument to the server side function.
google.script.run.writeCustomValue(valueToWrite);
google.script.host.close();
}
</script>
</body>
</html>
Here's what I've tried:
- Putting
host.close()
in a success handler:
google.script.run.withSuccessHandler(google.script.host.close()).writeCustomValue(valueToWrite);
- Async/await:
async function writeResponse(){
document.getElementById('writeResponse').innerHTML = 'Saving ...';
document.getElementById('writeResponse').disabled = true;
//Get the value of the input field
var valueToWrite = document.getElementById('valueToWrite').value;
//Send the value of the text field as an argument to the server side function.
await google.script.run.writeCustomValue(valueToWrite);
google.script.host.close();
}