2

I'm using Google Forms to feed a Google Doc (via Google Sheets), and in this Google Doc I have a pre-existing bulleted list. I would like to enter code that will add another bullet to the list.

My approach has been to add a ###newLine### tag to the end of the last pre-filled bullet in the form. I then used replace.Text(###newLine###) in GAS, and then added '\n' for a new line.

The problem is that this '\n' inserts a soft line break (like a Shift+Enter), and it doesn't create a new bullet. It just creates a new line under the prior bullet. I have tested within the doc by adding/removing the bullet associated with the above paragraph, and it is clear that this new line is associated with the above paragraph. What I would like is a a hard line break (like simply pressing Enter) which will create a new bullet.

Here's what the code looks like:

body.replaceText('###newLine###', '\n' + 'Produces a soft (shift+enter) line break.');

Also tried:

body.appendParagraph(). 

This attached to the end of the body and didn't seem to replaceText.

var insertPar = body.insertParagraph(21, 'test insert paragraph');
body.replaceText('###newBullet###', insertPar);

This would put it in the right spot but not as part of the list.

var listItemTest = body.appendListItem('#listItemTest#');
body.replaceText('###newBullet###', listItemTest);

This appended a numbered list to the end of the body but would not replace text or add to the existing bulleted list.

08-03-19, I tried the following, per Jescanellas's assistance. It works perfectly in the original test doc I provided, but I can't port it over to other docs. I think that's because I'm somehow failing to get the right data to attach it to the list at the right level, but I'm not sure where I'm messing up.

  var formDataEntered = functionName.values[11] || ''; //This var is retrieved from the sheet attached to a form. It's the submitted data.
  var listItem = body.getListItems(); //We're getting the list.

   for (var i = 0; i < listItem.length;i++){ //We're creating a loop here.
     var item = body.getListItems()[i]; //This gets the list and applies the loop to it.

     if ((item.findText('###bulletTestPlaceholder###')) && (formDataEntered != '')){ //The ###bulletTestPlaceholder### is just a placeholder in the doc where I want to insert the bullet. Your purpose with the item.findText is to identify the list level we're going for - NOT to use the text itself as a placeholder and replace the text. 

        var index = body.getChildIndex(item); //You're getting all the data about var item (where we got the list and applied the loop).
        var level = item.getNestingLevel();  //This gets the nesting level of var item. I'm wondering if this might be the issue as it's not specific to the findText('###bulletTestPlaceholder###')?
        var glyph = item.getGlyphType(); //This gets the bullet type. 

        body.insertListItem((index + 1), formDataEntered).setNestingLevel(level).setGlyphType(glyph); //This is the location in the list where teh bullet will be placed. It also sets the nesting level and glyph type. I've tried playing with the nesting level using integers, but that doesn't fix it.

        item.replaceText('###bulletTestPlaceholder###',''); //removes '###bulletTestPlaceholder###' text after it's no longer needed.

        break; //stops the loop from looping multiple times.

     } else if ((item.findText('###bulletTestPlaceholder###')) && (formDataEntered == '')) {
       item.replaceText('###bulletTestPlaceholder###',''); //removes '###bulletTestPlaceholder###' text and avoids new line if no formDataEntered
     }

  }
Jescanellas
  • 2,555
  • 2
  • 9
  • 20
Tom G
  • 21
  • 1
  • 5
  • Hi Tom and welcome to Stack Overflow! It would improve your question if you could edit it to include the code you have written so far :) – HFBrowning Jul 29 '19 at 21:37
  • Thank you for the feedback. I've added the relevant line. – Tom G Jul 29 '19 at 22:47
  • How about adding a new paragraph with [body.appendParagraph()](https://developers.google.com/apps-script/reference/document/paragraph)? – Jescanellas Jul 30 '19 at 11:03
  • @Jescanellas, Thank you for the reply. I edited my original post with new things I tried (including body.appendParagraph). Just discovered this and I think the solution might be in here (https://stackoverflow.com/questions/17773938/add-a-list-item-through-javascript), but I'll have to come back to it tomorrow. Thank you for the help and patience. I'm brand new to this stuff. – Tom G Aug 01 '19 at 10:04
  • Sorry, now I'm not sure what you are trying to do. I understand you have a bullet list, with several items, and you add ###newBullet## to the last of them to replace it with some other text. Is the final objective to add an item to the list? Can you post an example of the list and the result you want? Thanks. – Jescanellas Aug 01 '19 at 13:08
  • @Jescanellas, I've tried a range of other things. Poor hygiene across my prior experiments here (very green, as is probably obvious, so I've learned a good lesson to keep better track of what I've tried). Looks like the solution is more complicated than I expected (by my noob standards), but I think it's probably in this. (https://stackoverflow.com/questions/46868193/more-efficient-way-to-append-a-list-item-after-some-text-in-google-docs) I'll play with that tomorrow. Just trying to build a tool to mass-generate some work-related docs. – Tom G Aug 02 '19 at 08:57
  • @Jescanellas, thank you again. I've made an example doc here (https://docs.google.com/document/d/1DR_cNi5E_NKnA6bsp4eyDRpThe3aVvJtppRmmWQ4lL4/edit?usp=sharing). In the doc, if data is entered into a form, I want to make ###formData### join the above UL at level 2. If not, I don't want that line there. That's why I initially tried ###origApproach### with replaceText ("" if no data and new line plus the data if data was entered), but new lines apparently don't work with UL. Hope this is clearer. I basically just want to add form data, if entered, as a new bullet to a pre-existing UL. – Tom G Aug 02 '19 at 09:27

1 Answers1

0

After some investigating, and thanks to your examples and links I think I got the solution of this. If there is any issue or I misunderstood something, please tell me and I will correct the post.

This searches for the word ###origApproach### in all the paragraphs (list items) and adds the ###formData### next to it. After this it removes the ###origApproach### paragraph. I commented some lines in case you don't want to remove it.

 function myFunction() {

  var body = DocumentApp.getActiveDocument().getBody();
  var listItem = body.getListItems();

   for (var i = 0; i < listItem.length;i++){
     var item = body.getListItems()[i];

     if (item.findText('###origApproach###')){

        var index = body.getChildIndex(item);
        var level = item.getNestingLevel();      
        var glyph = item.getGlyphType();
        //In case the indentation is changed:
        var indentFirst = item.getIndentFirstLine();
        var indentStart = item.getIndentStart();

        //Added both setIndents to fix the indentation issue. 
        body.insertListItem((index + 1), '###formData###').setNestingLevel(level).setGlyphType(glyph).setIndentFirstLine(indentFirst).setIndentStart(indent);
        body.removeChild(item); //Comment this if you don't want to remove the  ###origApproach### paragraph

        //Uncomment this if you want to keep the paragraph and remove ###origApproach###
        //item.replaceText('###origApproach###','');
        break;

    }

  }
}

If you remove the paragraph with the word ###origApproach### change index + 1 to index

EDIT

If it's changing your glpyh style, you can force it by using the parameters BULLET, HOLLOW_BULLET, NUMBER, etc instead of the variable glyph.

You can read more about these functions here

Jescanellas
  • 2,555
  • 2
  • 9
  • 20
  • @Jescanelllas, thank you! It seems to work! I have to play with it a bit to make it work in my original doc, but that's my fault because the example is structured differently. I should have thought about that. Going to deconstruct and try to learn from what you've done here. I might bug you with more questions, if that's alright. Thank you for helping me out! This was more involved than I expected (but, again, I'm super green, so everything is a surprise right now). – Tom G Aug 02 '19 at 21:57
  • 1
    I've upvoted you but I got this message "Thanks for the feedback! Votes cast by those with less than 15 reputation are recorded, but do not change the publicly displayed post score." Just wanted you to know your help isn't unappreciated, @Jescanellas. – Tom G Aug 02 '19 at 21:58
  • it works perfectly in the prior test doc, but when I plug it into a new doc, it changes the list type and the bullet indentations. Here's what's happening: (https://docs.google.com/document/d/1i9-Z1kJHeEWAfYNPFRdjVezbpmNFLllLc19N9Q8jI70/edit?usp=sharing). I think I must be missing something really simple here. I've edited my question to show what i've played with and how I understand your code to work. I've tried to make it a little more intuitive. Thank you for your patience and help! – Tom G Aug 03 '19 at 22:02
  • You are welcome :). I can't understand why is it changing the indentation since, when I did the tests, it shows the word is placed correctly, just like the other bullets. I edited to my answer to fix this issue. – Jescanellas Aug 05 '19 at 07:53
  • Thank you! That makes sense. So we're specifying the bullet type and indentation to override whatever's causing the change. Curious, for me, I'm having the primary list change to a numbered list. Any idea what might cause that? Here's an example where the insert worked, but the list type changed. https://docs.google.com/document/d/1LMQXYCfEOKYRUIJBiQzBx7f5TApD9bZJu_6thJS-6Bg/edit?usp=sharing – Tom G Aug 09 '19 at 08:12