Apps Script - Google Form to Email PDF - Need Checkbox questions to generate as Bullet Points

Viewed 274

When Google Form is submitted, it finds the items to replace in the Google Doc template, then emails to me. I am having trouble getting the Form checkbox Response as bullet points in the Doc. It currently will list all options that were checked but they are separated by commas, not bullet points.

Any help on this would be really appreciated!

function onFormSubmit(e) {
  //open the template document by ID
  //you can find the ID in the link of the document
  var templateDoc = DriveApp.getFileById('1Dwbjh1Jqerg_WKvqdERyCfnDnWY2yjNArGY_f38ioAs');
  //create a copy of the template, we don't wanna mess up the template doc
  var newTempFile = templateDoc.makeCopy();
  
  //open the new template document for editing
  var openDoc = DocumentApp.openById(newTempFile.getId());
  var body = openDoc.getBody();
  
  //get the responses triggered by On Form Submit
  var items = e.response.getItemResponses();
  
  //find the text in the template doc and replace it with the Form response
  //items[0].getResponse() is the first response in the Form
  //and it is the "Name"
  body.replaceText('{Position}', items[0].getResponse());  
  //items[1].getResponse() is the second and it is the date
  body.replaceText('{Location}', items[1].getResponse());
  
  //You can add as much as you have and change them in the Template Doc like this
  body.replaceText('{Days/Hours}', items[2].getResponse());
  body.replaceText('{Qualifications}', items[3].getResponse());
  body.replaceText('{Duties}', items[4].getResponse());
  //and so on...
  
  //Save and Close the open document
  openDoc.saveAndClose();
  
  var theBlob = newTempFile.getBlob().getAs('application/pdf');
  //The name of the file is going to be the first and second question from the form
  //change to your preference
  var nameFile = items[0].getResponse() + '-' + items[1].getResponse() + '.pdf';

  //send an email with the PDF
  //If you don't want to send the PDF in the mail just delete everything
  //from here -------
  var email = 'youremail@email.com';
  var subject = 'Your new document';
  var body = 'Hello, <br/>Check this PDF file.';
  GmailApp.sendEmail(email, subject, body, {
    htmlBody: body,
    attachments: [{
      fileName: nameFile,
      content: theBlob.getBytes(),
      mimeType: "application/pdf"
      }]
   });
  //to here ------

  // save the PDF file in your Drive
  
  var savePDF = DriveApp.createFile (theBlob);

  //if you want to save the file in a specific folder use this code
  //get the ID from the folder link
  //var folder = DriveApp.getFolderById('14nUc----------0lUb');
  //var savePDF = folder.createFile (theBlob);

  savePDF.setName(nameFile);
  
  //delete the temp file
  DriveApp.getFileById(newTempFile.getId()).setTrashed(true);
}

1 Answers

You can't directly replace a text with multiple bullets.

First, you need to find where the element is. And instead of replacing text directly, you need to traverse the elements returned by the checkbox response and then append them one by one below the list/bullet containing the placeholder text. After appending all the elements, remove the placeholder text and its bullet.

To do those, I've added two separate functions. First is for appending new list items to a placeholder bullet and the other one is for removing the placeholder bullet after adding all those new list items. See code below.

Code:

// make sure to copy the original template, and use that copy instead of directly editing the original template which what I did below

var templateDoc = DriveApp.getFileById('1Ep2yDj-EZohCQAZl-TV1iiFqfTdHulffAiHJWH_8YFY');
var openDoc = DocumentApp.openById(templateDoc.getId());
var body = openDoc.getBody();

function onFormSubmit(e) {
  var items = e.response.getItemResponses();
  items.forEach(function (item, index) {
    switch (index){
      case 0:
        body.replaceText('{Position}', item.getResponse());  
        break;
      case 1:
        body.replaceText('{Location}', item.getResponse());
        break;
      case 2:
        body.replaceText('{Days/Hours}', item.getResponse());
        break;
      case 3:
        replaceBullet('{Qualifications}', item);
        break;   
      case 4:
        replaceBullet('{Duties}', item);
        break;   
      default:
        break;
    }
  });
  // Now, we finished replacing the values we need to be replaced
  // Add here the saving and closing of the document.
  // Then prepare your send email code here.
}

function replaceBullet(template, item) {
  var choices = item.getResponse();
  choices.forEach(function (choice) {
    appendToList(choice, template);
  });
  removeListTemplate(template);
}

function appendToList(elementContent, template) {
  var childIndex = 0;
  for (var i = 0; i < openDoc.getNumChildren(); i++) {
    var child = openDoc.getChild(i);
    if (child.getType() == DocumentApp.ElementType.LIST_ITEM && child.asText().getText() == template){
      while(child.getType() == DocumentApp.ElementType.LIST_ITEM){
        child = openDoc.getChild(i);
        childIndex = body.getChildIndex(child);
        i++;
      }
      child = openDoc.getChild(i-2);
      var newElement = child.getParent().insertListItem(childIndex, elementContent).setGlyphType(DocumentApp.GlyphType.BULLET);
      newElement.setListId(child);
    }
  }
}

function removeListTemplate(template) {
  for (var i = 0; i < openDoc.getNumChildren(); i++) {
    var child = openDoc.getChild(i);
  
    if (child.getType() == DocumentApp.ElementType.LIST_ITEM && child.asText().getText() == template)
      child.removeFromParent();
  }
}

Output:

output1

output2

Note:

  • This will not work when the data the bullets are inside the table. That's why I removed the table and have 2 columns in the page instead.
  • Insert "column break" at the end of the first column so it will not shift when bullets are replaced by a different number of bullets
Related