I want to build multi-page sites using Google Apps Script. To do this, I would like to exploit the ability of doGet()
to process query strings. I am aware of at least one solution to this problem:
Linking to another HTML page in Google Apps Script
However, that solution seems overly restrictive, since it relies on GAS's templated html feature to build the proper URL with query string right within the HTML at page load-time. A more general-purpose solution would be to build the appropriate query string within a jquery (or javascript) function based on dynamic UI state and user interface actions. Is this possible? How can it be done?
Here is my proposal for a possible solution (which doesn't work!):
HTML/JQuery:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<title>Speedgolf Scoring</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
</head>
<body id = "mainBody">
<H1>LOGIN PAGE</H1>
<H3>Please choose interface:</H3>
<button id = "playerUI">Follow Player</button>
<button id = "holeUI">Follow Hole</button>
<button id = "flexUI">Roaming Scorer</button>
</body>
</html>
<script>
function loadNewPage(result, userObject) {
var newURL = result + userObject;
alert("Newly-constructed URL to be loaded: " + newURL); //CORRECT URL IS CONSTRUCTED BASED ON DEBUGGING OUTPUT!
window.open(newURL,"_self"); //<--THIS IS THE LINE THAT SHOULD INVOKE DOGET(). SERVER LOGS INDICATE DOGET() IS INVOKED, BUT NO PAGE IS VISIBLY SERVED.
}
$("#playerUI").click(function () {
alert("In player UI click...");
var newURL = "?mode=player";
google.script.run.withSuccessHandler(loadNewPage).withUserObject(newURL).getScriptURL();
//Execution continues in loadNewPage callback...
});
$("#holeUI").click(function () {
var newURL = "?mode=hole";
google.script.run.withSuccessHandler(loadNewPage).withUserObject(newURL).getScriptURL();
});
$("#flexUI").click(function () {
var newURL = "?mode=flex";
google.script.run.withSuccessHandler(loadNewPage).withUserObject(newURL).getScriptURL();
});
</script>
And my Code.gs file:
function getScriptURL() {
var url = ScriptApp.getService().getUrl();
Logger.log('In getScriptURL...Value of URL returned: ' + url);
return url;
}
function doGet(e) {
Logger.log('In doGet');
Logger.log('query params: ' + Utilities.jsonStringify(e));
if (e.queryString === '') {
Logger.log('Serving loginUI');
return HtmlService
.createHtmlOutputFromFile('loginUI')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Please log in");
}
//if here, we know query string is NOT null
if (e.parameter.mode == "player") {
Logger.log('Serving player UI');
return HtmlService
.createHtmlOutputFromFile('playerUI')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Following Player");
}
if (e.parameter.mode == "hole") {
Logger.log('Serving hole UI');
return HtmlService
.createHtmlOutputFromFile('holeUI')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Following Hole");
}
if (e.parameter.mode == "flex") {
Logger.log('Serving flex UI');
return HtmlService
.createHtmlOutputFromFile('flexUI')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Flex Interface");
}
}
I am able to verify, through server logs and alert boxes, that the correct URL with query string is built. I would expect this line of code:
$("#mainBody").load(newURL);
to invoke doGet()
and cause a new page to be loaded based on the query string. However, through my server logs, I observe that doGet()
is not invoked, and hence the new page I expect to be served is never served. What is happening? Why is doGet()
not invoked when I load a new page through jquery? How can I force doGet()
to be invoked? Thanks in advance!