Reputation: 2489
I have a Google Apps Script Webapp which serves a simple html form. My Apps Script function processData(formdata)
receives the form data as a Blob as described here . After I process the data I want to return another simple html page to the user. I tried the naive approach like this:
function processData(formdata){
// do something with the data
process(formdata);
return HtmlService
.createHtmlOutputFromFile('html/final')
}
However the page is always blank after the user submits the data. How can I give the user a proper response?
This is my second approach as suggested by @Cooper. I added it in the html and used the withSuccessHandler
but the page remains white after submitting:
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"
/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script>
function updateUrl() {
var div = document.getElementById('msg');
div.innerHTML = "<h1>Thanks for the submission</h1><p>You should be hearing from us soon</p>";
}
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
}
</script>
</head>
<body>
<div id="msg"></div>
<div class="container">
<h1>FORM insert data</h1>
<form id="myForm" onsubmit="handleFormSubmit(this)">
<div class="form-group">
<label for="nameInput">enter your name</label><br />
... and so on
[Edit]
I now added the preventFormSubmit
function as described in the example by Cooper. Now after submitting the message is shown. However the complete form stays on the page where I would prefere to only have the message be shown.
That said it seems that it is not easy to just show another html. Does that mean it is not possible to have a more complex webapp which require more html sides with Google Apps Script?
Upvotes: 1
Views: 688
Reputation: 64062
You were right there were some problems with that example that are a result of the recent switch to the v8 engine. I didn't use the doGet(), I ran it as a dialog instead. But here's a working version.
Code.gs:
function runADialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'), 'MCVE')
}
function processForm(data) {
SpreadsheetApp.getActive().toast('processForm');
console.log('processForm');
var file = Utilities.newBlob(data.bytes,data.mimeType,data.name)
var driveFile = DriveApp.createFile(file);
return driveFile.getUrl();
}
ah1.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function preventFormSubmit() {
var forms=document.querySelectorAll('form');
for (var i=0;i<forms.length;i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
console.log('handleFormSubmit');
const file = formObject.myFile.files[0];
console.log(file);
const fr = new FileReader();
fr.onload = function(e) {
const obj = {name:file.name,mimeType: file.type,bytes:[...new Int8Array(e.target.result)]};
google.script.run.withSuccessHandler(updateUrl).processForm(obj);
}
fr.readAsArrayBuffer(file);
}
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = '<a href="' + url + '">Got it!</a>';
}
</script>
</head>
<body>
<form id="myForm" onsubmit="handleFormSubmit(this)">
<input name="myFile" type="file" />
<input type="submit" value="Submit" />
</form>
<div id="output"></div>
</body>
</html>
Most of the modifications for this example came from Tanaike
This is what the dialog looks like when it works:
and you can click on that link to go to the file.
And this is a version using that other div I was talking about.
Code.gs:
function runADialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'), 'MCVE')
}
function processForm(data) {
SpreadsheetApp.getActive().toast('processForm');
console.log('processForm');
var file = Utilities.newBlob(data.bytes,data.mimeType,data.name)
var driveFile = DriveApp.createFile(file);
return driveFile.getUrl();
}
function getServerInfo() {
//getting nothing for now
return{msg:"This is the default message."};
}
ah1.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
function preventFormSubmit() {
var forms=document.querySelectorAll('form');
for (var i=0;i<forms.length;i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
console.log('handleFormSubmit');
const file = formObject.myFile.files[0];
console.log(file);
const fr = new FileReader();
fr.onload = function(e) {
const obj = {name:file.name,mimeType: file.type,bytes:[...new Int8Array(e.target.result)]};
google.script.run
.withSuccessHandler(function(url){
updateUrl(url);
google.script.run
.withSuccessHandler(function(obj){
document.getElementById("msg").innerHTML="<h1> Thanks for Submitting that Image<h1><p>" + obj.msg + "</p>";
})
.getServerInfo();
})
.processForm(obj);
}
fr.readAsArrayBuffer(file);
}
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = '<a href="' + url + '">Got it!</a>';
}
</script>
</head>
<body>
<form id="myForm" onsubmit="handleFormSubmit(this)">
<input name="myFile" type="file" />
<input type="submit" value="Submit" />
</form>
<div id="output"></div>
<div id="msg"></div>
</body>
</html>
And this is what the new dialog looks like:
Upvotes: 2