Direct to a new page after form submission

2019-08-23 03:34发布

问题:

Currently I've developed a Google Scripts API which is used for people to upload files to a shared Google Drive folder. After the file are uploaded successfully, I want them to be taken to a separate "Thank you" page so it is clear their upload has worked. Currently I only have a message on the same page to this effect and I cannot figure out how to direct to a new page that I have created.

This is the additional bit I found from different questions to try direct to a new page however this is not working so far, as it remains on the same upload form page. I have included it at the bottom of my code.gs file. Any ideas on how to direct to a custom page that just says "thank you" or something similar would be great!

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

The rest of my code is as follows:

Code.gs:

 function doGet() {
        return HtmlService.createHtmlOutputFromFile('form').setSandboxMode(
                HtmlService.SandboxMode.IFRAME);
    }

function createFolder(parentFolderId, folderName) {
    try {
        var parentFolder = DriveApp.getFolderById(parentFolderId);
        var folders = parentFolder.getFoldersByName(folderName);
        var folder;
        if (folders.hasNext()) {
            folder = folders.next();
        } else {
            folder = parentFolder.createFolder(folderName);
        }
        return {
            'folderId' : folder.getId()
        }
    } catch (e) {
        return {
            'error' : e.toString()
        }
    }
}

function uploadFile(base64Data, fileName, folderId) {
    try {
        var splitBase = base64Data.split(','), type = splitBase[0].split(';')[0]
                .replace('data:', '');
        var byteCharacters = Utilities.base64Decode(splitBase[1]);
        var ss = Utilities.newBlob(byteCharacters, type);
        ss.setName(fileName);

        var folder = DriveApp.getFolderById(folderId);
        var files = folder.getFilesByName(fileName);
        var file;
        while (files.hasNext()) {
            // delete existing files with the same name.
            file = files.next();
            folder.removeFile(file);
        }
        file = folder.createFile(ss);
        return {
            'folderId' : folderId,
            'fileName' : file.getName()
        };
    } catch (e) {
        return {
            'error' : e.toString()
        };
    }
}

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

Form.html:

<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>


<body>

<div align="center">
  <p><img src="https://drive.google.com/uc?export=download&id=0B1jx5BFambfiWDk1N1hoQnR5MGNELWRIM0YwZGVZNzRXcWZR"
  height="140" width="400" ></p>
<div>

    <form id="uploaderForm">
        <label for="uploaderForm">  <b> Welcome to the Tesco's animal welfare and soy reporting system. </b> </label>
<BR>
<BR>


<div style="max-width:500px; word-wrap:break-word;">

Please add your contact information below and attach a copy of your company's animal welfare standard before clicking submit. Wait for the browser to confirm your submission and you may then close this page.

<BR>
<BR>

Thank you very much for your submission.

</div>

<BR>
<BR>
        <div>
            <input type="text" name="applicantName" id="applicantName"
                placeholder="Your Name">
        </div>

<BR>
        <div>
            <input type="text" name="applicantEmail" id="applicantEmail"
                placeholder="Your Company">
        </div>

<BR>
<BR>
        <div>
            <input type="file" name="filesToUpload" id="filesToUpload" multiple>
            <input type="button" value="Submit" onclick="uploadFiles()">
        </div>
    </form>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <div id="output"></div>
    <script>
        var rootFolderId = '1-aYYuTczQzJpLQM3mEgOkWsibTak7KE_';
        var numUploads = {};
        numUploads.done = 0;
        numUploads.total = 0;
        // Upload the files into a folder in drive
        // This is set to send them all to one folder (specificed in the .gs file)
        function uploadFiles() {
            var allFiles = document.getElementById('filesToUpload').files;
            var applicantName = document.getElementById('applicantName').value;
            if (!applicantName) {
                window.alert('Missing applicant name!');
            }
            var applicantEmail = document.getElementById('applicantEmail').value;
            if (!applicantEmail) {
                window.alert('Missing applicant email!');
            }
            var folderName = applicantEmail;
            if (allFiles.length == 0) {
                window.alert('No file selected!');
            } else {
                numUploads.total = allFiles.length;
                google.script.run.withSuccessHandler(function(r) {
                    // send files after the folder is created...
                    for (var i = 0; i < allFiles.length; i++) {
                        // Send each file at a time
                        uploadFile(allFiles[i], r.folderId);
                    }
                }).createFolder(rootFolderId, folderName);
            }
        }
        function uploadFile(file, folderId) {
            var reader = new FileReader();
            reader.onload = function(e) {
                var content = reader.result;
                document.getElementById('output').innerHTML = 'uploading '
                        + file.name + '...';
                //window.alert('uploading ' + file.name + '...');               
                google.script.run.withSuccessHandler(onFileUploaded)
                        .uploadFile(content, file.name, folderId);
            }
            reader.readAsDataURL(file);
        }
        function onFileUploaded(r) {
            numUploads.done++;
            document.getElementById('output').innerHTML = 'uploaded '
                    + r.fileName + ' (' + numUploads.done + '/'
                    + numUploads.total + ' files).';
            if (numUploads.done == numUploads.total) {
                document.getElementById('output').innerHTML = 'All of the '
                        + numUploads.total + ' files are uploaded';
                numUploads.done = 0;
            }
        }
    </script>

        <label for="uploaderForm"> 

Powered by 3Keel 
</label>
</body>


</html>

Thanks.html:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    Thank you for submitting!
  </body>
</html>

EDIT:

I have changed this function as recommended:

        if (numUploads.done == numUploads.total) {
            window.location = 'Thanks.html';
            numUploads.done = 0;

Now it is redirecting to another page but I am faced with this error:

  1. That’s an error.

The requested URL was not found on this server. That’s all we know.

回答1:

If you are looking for the solution of your issue yet, how about this answer?

  • You want to open Thanks.html when the process at Form.html is finished.
  • Form.html and Thanks.html are put in a project.

If my understanding is correct, how about this workaround? I have ever experienced with your situation. At that time, I could resolve this issue by this workaround.

Modification points:

  • It is not required to use doPost() to access to Thanks.html. I think that you can achieve what you want using doGet().
  • I think that @Scott Craig's answer can be also used for this situation. In my workaround, the URL of window.location = 'Thanks.html'; is modified.
    • Uses the URL of deployed Web Apps. In your script, when users access to your form, they access to the URL of the deployed Web Apps. In this workaround, it is used by adding a query parameter.

Modified scripts:

Form.html

For the script added in your question as "EDIT", please modify as follows.

From:
window.location = 'Thanks.html';
To:
window.location = 'https://script.google.com/macros/s/#####/exec?toThanks=true';

https://script.google.com/macros/s/#####/exec is the URL of the the deployed Web Apps. Please add a query parameter like toThanks=true. This is a sample query parameter.

Code.gs

Please modify doGet() as follows.

From:
function doGet() {
  return HtmlService.createHtmlOutputFromFile('form')
  .setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
To:
function doGet(e) {
  if (e.parameter.toThanks) {
    return HtmlService.createHtmlOutputFromFile('Thanks')
    .setSandboxMode(HtmlService.SandboxMode.IFRAME)
    .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  } else {
    return HtmlService.createHtmlOutputFromFile('form')
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  }
}

Note:

  • When the script of the deployed Web Apps was modified, please redeploy it as new version. By this, the latest script is reflected to Web Apps.
  • The flow of this modified script is as follows.
    • When users access to the Form.html, because the query parameter of toThanks=true is not used, Form.html is returned.
    • When onFileUploaded() is run and if (numUploads.done == numUploads.total) {} is true, it opens the Web Apps URL with the query parameter of toThanks=true. By this, if (e.parameter.toThanks) {} of doGet() is true, and Thanks.html is returned and opened it.

In my environment, I could confirm that this modified script worked. But if this didn't work in your environment, I'm sorry. At that time, I would like to think of about the issue.



回答2:

I might be misunderstanding your question, but from what I understand, instead of this line:

document.getElementById('output').innerHTML = 'All of the '
                    + numUploads.total + ' files are uploaded';

You want to redirect to Thanks.html. If that's correct, just replace the above line with:

window.location = 'Thanks.html';