Introduction
I am creating a Google Script that fills a Google Doc template based on the fields of a Google Forms and sends the generated PDF via email to the user. Now I need to implement the possibility that the user can edit its submit after he press on "Send Form".
This is the Doc template example:
This is how the Spreadsheet looks like (2nd row is added by me for columns enumeration):
Time stamp | Dirección de correo electrónico | Surname | First name | Year | Model | Birthday (1) | Car (1) | Add a new row? | Birthday (2) | Car (2) | Add a new row? | Birthday (3) | Car (3) | When |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
2/04/2021 20:30:53 | example1@gmail.com | A | F1 | 2005 | Z | 15/03/2008 | MM | Y | 12/12/1996 | - | N | 3/05/2009 | ||
2/04/2021 20:31:05 | example2@gmail.com | B | F2 | 2006 | X | 3/02/2005 | WW | N | 24/08/2000 | |||||
3/04/2021 21:40:04 | example3@gmail.com | C | F3 | 2018 | Y | - | TT | Y | 3/03/2004 | 54 | Y | - | 43 | 24/12/2019 |
Script
Thanks to Rubén's answer I could handle some fields. This is my code so far:
function onSubmit(e) { // Function taken from https://medium.com/swlh/hacking-it-generate-pdfs-from-google-forms-3ca4fcc5a0aa
const rg = e.range;
const sh = rg.getSheet();
const values = e.range.getValues().flat();
const cEmail = e.namedValues['Dirección de correo electrónico'][0] ? e.namedValues['Dirección de correo electrónico'][0] : values[1];
const cSurname = e.namedValues['Surname'][0] ? e.namedValues['Surname'][0] : values[2];
const cFirstName = e.namedValues['First name'][0] ? e.namedValues['First name'][0] : values[3];
const cYear = e.namedValues['Year'][0] ? e.namedValues['Year'][0] : values[4];
const cModel = e.namedValues['Model'][0] ? e.namedValues['Model'][0] : values[5];
// EXTRACT DAY, MONTH AND YEAR from https://stackoverflow.com/a/66909780/11617040
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
// Birthday 1
var dateStrBirthday1 = e.namedValues['Birthday (1)'][0] ? e.namedValues['Birthday (1)'][0] : values[6];
var dateArrBirthday1 = dateStrBirthday1.split("/");
var newDateBirthday1 = dateArrBirthday1[1] + "/" + dateArrBirthday1[0] + "/" + dateArrBirthday1[2];
var dateBirthday1 = new Date(newDateBirthday1);
var cBDay1 = dateBirthday1.getDate();
var cBMonth1 = dateBirthday1.getMonth()+1; // To use month with letters write monthNames[cMonth]
var cBYear1 = dateBirthday1.getFullYear();
// Birthday 2
var dateStrBirthday2 = e.namedValues['Birthday (2)'][0] ? e.namedValues['Birthday (2)'][0] : values[9];
var dateArrBirthday2 = dateStrBirthday2.split("/");
var newDateBirthday2 = dateArrBirthday2[1] + "/" + dateArrBirthday2[0] + "/" + dateArrBirthday2[2];
var dateBirthday2 = new Date(newDateBirthday2);
var cBDay2 = dateBirthday2.getDate();
var cBMonth2 = dateBirthday2.getMonth()+1; // To use month with letters write monthNames[cMonth]
var cBYear2 = dateBirthday2.getFullYear();
// Birthday 3
var dateStrBirthday3 = e.namedValues['Birthday (3)'][0] ? e.namedValues['Birthday (3)'][0] : values[12];
var dateArrBirthday3 = dateStrBirthday3.split("/");
var newDateBirthday3 = dateArrBirthday3[1] + "/" + dateArrBirthday3[0] + "/" + dateArrBirthday3[2];
var dateBirthday3 = new Date(newDateBirthday3);
var cBDay3 = dateBirthday3.getDate();
var cBMonth3 = dateBirthday3.getMonth()+1; // To use month with letters write monthNames[cMonth]
var cBYear3 = dateBirthday3.getFullYear();
const cCar = [];
for (var i=1; i<=3; i++) {
cCar.push(e.namedValues['Car (' + i + ')'][0] ? e.namedValues['Car (' + i + ')'][0] : values[7+(i-1)*3]);
}
const cWhen = e.namedValues['When'][0] ? e.namedValues['When'][0] : values[14];
//Build a new invoice from the file
//Folder and file IDs
const folderAnswersID = '....';
const folderAnswers = DriveApp.getFolderById(folderAnswersID);
// Add actual time to the file name
var today = new Date();
const newFileName = 'Example - ' + cSurname + ' ' + cFirstName + ' ' + today.getDate() + ' ' + (today.getMonth()+1) + ' ' + today.getFullYear() + ' ' + today.getHours() + '_' + today.getMinutes();
const temapleFileID = '........';
//Make a copy of the template file
const newAnswersFileID = DriveApp.getFileById(temapleFileID).makeCopy(newFileName, folderAnswers).getId();
//Get the invoice body into a variable
var document = DocumentApp.openById(newAnswersFileID);
var body = document.getBody();
//Replace all the < > text in the invoice body
body.replaceText('<Surname>', cSurname);
body.replaceText('<FirstName>', cFirstName);
body.replaceText('<Year>', cYear);
body.replaceText('<Model>', cModel);
body.replaceText('<BDay1>', cBDay1);
body.replaceText('<BDay2>', cBDay2);
body.replaceText('<BDay3>', cBDay3);
body.replaceText('<BMonth1>', cBMonth1);
body.replaceText('<BMonth2>', cBMonth2);
body.replaceText('<BMonth3>', cBMonth3);
body.replaceText('<BYear1>', cBYear1);
body.replaceText('<BYear2>', cBYear2);
body.replaceText('<BYear3>', cBYear3);
for (var i=1; i<=3; i++) {
body.replaceText('<Car' + i + '>', cCar[i-1]);
}
body.replaceText('<When>', cWhen);
document.saveAndClose();
// From https://stackoverflow.com/a/66862676/11617040
var docblob=document.getAs('application/pdf').setName(newFileName + '.pdf');
var dupdocs=folderAnswers.getFilesByName(newFileName);
while(dupdocs.hasNext()) {
dupdocs.next().setTrashed(true);
}
var file=folderAnswers.createFile(docblob);
var emailTitle = 'Your answer was submitted!';
var emailBody = 'Dear <b>' + cSurname + '</b>:<br><br>The document <b>' + newFileName + '</b> was submitted correctly. Please see the attachment.';
var attachment = DriveApp.getFileById(newAnswersFileID);
GmailApp.sendEmail(
cEmail,
emailTitle,
"",
{
htmlBody: emailBody,
attachments: [attachment.getAs(MimeType.PDF)]
}
);
}
I also have 2 triggers:
- On submit: When the user press "Send Form".
- Edit: When the user edits its Form after he press "Send Form".
There are 2 types of "Fields" that I need to care about:
- "Non-repetitive fields": Surname, First name, Year, Model, WHEN. These fields do not require a
for
loop so the code is not so long:- "Non-date fields": Surname, First name, Year. They aren't special.
- "Date fields": WHEN. This is a Date field on Google Forms but nothing special.
- "Repetitive fields": Day, Month, Year, Car. These fields do require a
for
loop so the code is not so long:- "Non-date fields": Car. I created a
for
loop for this field. - "Date fields": Day, Month, Year. These fields were Date fields but they need to be separated so I have days, months and years separately. This was solved in a previous question but I don't know how to make a
for
loop for this ones.
- "Non-date fields": Car. I created a
Test and results
The user submits the 1st row:
2/04/2021 20:30:53 | example1@gmail.com | A | F1 | 2005 | Z | 15/03/2008 | MM | Y | 12/12/1996 | - | N | 3/05/2009 |
---|
This is the output:
Problem
There are a NaN
values that I don't want them to appear. Instead they should be blank. How to solve this?