0

I've assigned a variable:Serial in Google apps script (code.gs) and want to fetch the value in (success.html) page after form submission. Here is my code.gs

function doPost(e) {
  const folderId = "root"; // Or Folder ID which is used for putting the file instead of "root", if you need.
  const sheetId = "<sheetid>"; // Replace with your sheet ID
  const sheet = SpreadsheetApp.openById(sheetId).getSheetByName("sheet1"); 

  const name = e.parameter.name;
  const email = e.parameter.email;
  const file = e.postData.contents ? Utilities.newBlob(JSON.parse(e.postData.contents), e.parameter.mimeType, e.parameter.filename) : null;

    var currentDate = new Date();
  var month = currentDate.toLocaleString('default', { month: 'short' });
  var year = currentDate.getFullYear().toString().substr(-2);
  
  var serialNumber = 'D' + month + year + pad(sheet.getLastRow() + 1, 4);
  function pad(num, length) {
  var str = num.toString();
  while (str.length < length) {
    str = '0' + str;
  }
  return str;
}

  if (file) {
    const uploadedFile = DriveApp.getFolderById(folderId).createFile(file);
    const responseObj = { filename: uploadedFile.getName(), fileId: uploadedFile.getId(), fileUrl: uploadedFile.getUrl(), name: name, email: email };

    const sheet = SpreadsheetApp.openById(sheetId).getSheetByName("sheet1"); // Replace "Sheet1" with the name of your sheet
    sheet.appendRow([serialNumber, name, email, uploadedFile.getUrl()]);

        //return ContentService.createTextOutput("Form Submitted Successfully");

    return ContentService.createTextOutput(JSON.stringify(responseObj)).setMimeType(ContentService.MimeType.JSON);
  } else {
    const sheet = SpreadsheetApp.openById(sheetId).getSheetByName("sheet1"); // Replace "Sheet1" with the name of your sheet
    sheet.appendRow([serialNumber, name, email, ""]); // Replace "" with the default values for other columns if needed

        //return ContentService.createTextOutput("Form Submitted Successfully");

    return ContentService.createTextOutput(JSON.stringify({ name: name, email: email })).setMimeType(ContentService.MimeType.JSON);
  }
}
function doGet() {
  return HtmlService.createHtmlOutputFromFile("success.html").setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

And here is my success.html code

<!DOCTYPE html>
<html>
  <head>
    <title>Thank You!</title>
  </head>
  <body>
    <h1>Thank you for submitting the form!</h1>
    <h2><?= serialNumber ?></h2>
  </body>
</html>

Need value of serial variable in success.html i.e, assigned in code.js. note: this question related to my last question refer Here

Sandeep
  • 15
  • 6

1 Answers1

1

In your situation, I think that the client HTML form is used. The sample flow is as follows.

  1. At the client side, upload a file from the client HTML form.
  2. At the Web Apps side, serialNumber is created and returned it.
  3. At the client side, the obtained value of serialNumber is sent with the URL of Web Apps.
  4. At the Web Apps side, success.html is opened by reflecting serialNumber as the template.

When this flow is reflected in your script, it becomes as follows.

Google Apps Script side:

In this case, success.html is not modified.

function doGet(e) {
  const html = HtmlService.createTemplateFromFile("success.html");
  html.serialNumber = e.parameter.serialNumber;
  return html.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

function doPost(e) {
  const folderId = "root"; // Or Folder ID which is used for putting the file instead of "root", if you need.
  const sheetId = "<sheetid>"; // Replace with your sheet ID
  const sheet = SpreadsheetApp.openById(sheetId).getSheetByName("sheet1");
  const name = e.parameter.name;
  const email = e.parameter.email;
  const file = e.postData.contents ? Utilities.newBlob(JSON.parse(e.postData.contents), e.parameter.mimeType, e.parameter.filename) : null;
  var currentDate = new Date();
  var month = currentDate.toLocaleString('default', { month: 'short' });
  var year = currentDate.getFullYear().toString().substr(-2);
  var serialNumber = 'D' + month + year + pad(sheet.getLastRow() + 1, 4);
  function pad(num, length) {
    var str = num.toString();
    while (str.length < length) {
      str = '0' + str;
    }
    return str;
  }
  if (file) {
    const uploadedFile = DriveApp.getFolderById(folderId).createFile(file);
    const responseObj = { filename: uploadedFile.getName(), fileId: uploadedFile.getId(), fileUrl: uploadedFile.getUrl(), name: name, email: email, serialNumber };
    const sheet = SpreadsheetApp.openById(sheetId).getSheetByName("sheet1"); // Replace "Sheet1" with the name of your sheet
    sheet.appendRow([serialNumber, name, email, uploadedFile.getUrl()]);
    //return ContentService.createTextOutput("Form Submitted Successfully");
    return ContentService.createTextOutput(JSON.stringify(responseObj)).setMimeType(ContentService.MimeType.JSON);
  } else {
    const sheet = SpreadsheetApp.openById(sheetId).getSheetByName("sheet1"); // Replace "Sheet1" with the name of your sheet
    sheet.appendRow([serialNumber, name, email, ""]); // Replace "" with the default values for other columns if needed
    //return ContentService.createTextOutput("Form Submitted Successfully");
    return ContentService.createTextOutput(JSON.stringify({ name: name, email: email })).setMimeType(ContentService.MimeType.JSON);
  }
}

Client side: html

<!DOCTYPE html>
<html>
  <head>
    <title>File Upload to Google Drive with Name and Email Input</title>
  </head>
  <body>
    <form id="form">
      <label for="name">Name:</label>
      <input name="name" id="name" type="text"><br><br>
      <label for="email">Email:</label>
      <input name="email" id="email" type="email"><br><br>
      
      <label for="uploadfile">File:</label>
      <input name="file" id="uploadfile" type="file"><br><br>
      <label for="filename">File Name:</label>
      <input name="filename" id="filename" type="text"><br><br>
      
      <input id="submit" type="submit">
    </form>
    <script>
      const form = document.getElementById('form');
      form.addEventListener('submit', e => {
        e.preventDefault();
        const name = form.name.value;
        const email = form.email.value;
        const file = form.file.files[0];
        if (!file) {
          const url = "https://script.google.com/macros/s/###/exec"; // Please replace this with your Web Apps URL.
          const qs = new URLSearchParams({filename: "", mimeType: "", name: name || "", email: email || ""});
          fetch(`${url}?${qs}`, {method: "POST", body: JSON.stringify([])})
            .then(res => res.json())
            .then(e => {
              console.log(e);  // <--- You can retrieve the returned value here.
              window.open(url + "?serialNumber=" + e.serialNumber, '_self');
            })
            .catch(err => console.log(err));
          return;
        }
        const fr = new FileReader();
        fr.readAsArrayBuffer(file);
        fr.onload = f => {
          const url = "https://script.google.com/macros/s/###/exec"; // Please replace this with your Web Apps URL.
          const qs = new URLSearchParams({filename: form.filename.value || file.name, mimeType: file.type, name: name || "", email: email || ""});
          fetch(`${url}?${qs}`, {method: "POST", body: JSON.stringify([...new Int8Array(f.target.result)])})
            .then(res => res.json())
            .then(e => {
              console.log(e);  // <--- You can retrieve the returned value here.
              window.open(url + "?serialNumber=" + e.serialNumber, '_self');
            })
            .catch(err => console.log(err));
        }
      });
    </script>
  </body>
</html>
  • When this script is run, the above flow is run. By this, <?= serialNumber ?> of the template HTML is replaced with the value of serialNumber.

Note:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Hi @Tanaike, Hope you're doing well. Had an small doubt i.e, right now my success.html is added in Google apps script. What if success.html is client side(like in same hierarchy level of index.html) and want to redirect after form submission. Can you please tell me what can be done in this scenario ? – Sandeep Mar 27 '23 at 12:03
  • @Sandeep About your new question, I would like to support you. But the issue of replying is new issue, and that is different from your question. So can you post it as new question? Because when your initial question is changed by comment, other users who see your question are confused. By posting it as new question, users including me can think of it. If you can cooperate to resolve your new issue, I'm glad. Can you cooperate to resolve your new question? – Tanaike Mar 27 '23 at 12:11
  • Hi @Tanaike, Sure I've posted a new question regarding my query here:(https://stackoverflow.com/questions/75862227/how-to-redirect-to-other-client-html-page-and-also-get-variable-from-code-gs-to) – Sandeep Mar 28 '23 at 04:02
  • @Sandeep Thank you for replying. When I saw your new question, I noticed that an answer has already been posted. In this case, I would like to respect the existing answer. – Tanaike Mar 28 '23 at 06:29
  • yes, @Tanaike. It worked well. But i had an same query but a different scenario, can you answer this please. Here is my query: (https://stackoverflow.com/questions/75866808/how-to-redirect-to-client-html-in-google-apps-script) – Sandeep Mar 28 '23 at 13:24
  • Can you look into this query (https://stackoverflow.com/questions/75873720/get-variable-from-code-gsgoogle-apps-script-to-html-page-url-parameters) – Sandeep Mar 29 '23 at 06:42