4
votes

Say I have an HTML file with various inputs. According to these inputs I would like to send an email and then display a thank you message or redirect to a thank you page.

I am loading the index.html file in the doGet() as below:

function doGet(){
    var template = HtmlService.createTemplateFromFile('index');
    template.action = ScriptApp.getService().getUrl();
    return template.evaluate();
}

After adding the implementation which I require in doPost(e) function, deploying the code into a web app, filling in the form and submitting, everything seems to be working perfectly apart from the last bit. I want to show an output message or redirect to a thank you page, or something of the sort, but all I am seeing is a blank page, where there would have been the HTML form.

I have tried:

function doPost(e) {
    //all logic
    return ContentService.createTextOutput("Thank you");
}

And..

function doPost(e) {
    //all logic
    return ContentService.createTextOutput(JSON.stringify(e.parameter));
}

And..

function doPost(e) {
    //all logic
    var htmlBody = "<h1>Thank you.</h1>";
    return HtmlService.createHtmlOutput(htmlBody);
}

And..

function doPost(e) {
    //all logic
    var template = HtmlService.createTemplateFromFile('Thanks');
    return template.evaluate();
}

In all the listed cases the HTML form simply seems to disappear and I can only see a blank screen.

Any ideas?

1
It's pretty relevant to show how you are calling this doPost(e). Note that just because it returns some value doesn't mean that the code which calls the function uses the function's output. - tehhowch
According to the official documentation: A script can be published as a web app if it meets these requirements: It contains a doGet(e) or doPost(e) function.. The only way I can show you more, is by taking a video of myself doing all that I describe within my question. I would be glad to offer more detail, however, it seems more likely that you have never used Google Web Forms, and hence don't know that the doPost(e) function is actually automatically fired when submitting the form. - Jurgen Cuschieri
Your HTML form may have a button inside the form tags which causes the browser page to reload and remove the displayed content. This is a built-in design feature of HTML to try to prevent people from submitting duplicates. But, for people designing the HTML, it causes the problem that you are having. There are various ways to fix your problem. If you have an action attribute in the form tag to make a post request, then you must remove that. And you can't have the submit button inside of the form tags. - Alan Wells
If you do not bind the function call from an Apps Script webapp, i.e. google.script.run.withSuccessHandler(yourClientSideFunction).yourServerSideFunction(yourData), then you are simply discarding the return value of yourServerSideFunction. You have already loaded the webpage - returned by the doGet() function - and unless you indicate in your client side form submission code that the client HTML should be replaced with some other input HTML, that won't happen. You would do that in your success handler. - tehhowch
@SandyGood thanks for your reply. I have tried removing the action, the doPost() is fired, but the issue is not solved. Removing the submit button from inside the form tag simply does not submit the form on button click. How is the form submitted without a button inside it? - Jurgen Cuschieri

1 Answers

7
votes

In GAS, sending a POST request via web app is not as simple as it seems. Go ahead and try a little experiment: add the following JS code to the HTML page served by the doGet() function just before the closing <body> tag:

... 
<script>
console.log(window.location);
</script>
</body>

When inspecting the output in the console, you'll likely get something like:

enter image description here

The issue is that the web app URL ending with '/exec' doesn't actually link to self. Ratner, the googleusercontent.com link is the URL you'll be redirected to when opening links and forms. However, in order to get the form submit to work, the POST request should be sent to the "published" URL of your web app (the one ending with '/exec').

You must therefore override the defaults by implementing your own routing. There are many ways to achieve this result - here's the easiest one:

    <form method="post" action="<?!= ScriptApp.getService().getUrl() ?>">
    <input type="submit" value="submit">
    </form>

If the <?!= ?> notation looks unfamiliar to you, please check the section on scriptlets and HTML templates in GAS https://developers.google.com/apps-script/guides/html/templates

Basically, what happens is that the web app URL is force-printed to the template before raw HTML is sent to your browser for rendering. This makes sure you'll hit the correct URL when 'submit' event occurs.