google-apps-scriptgoogle-docsbulletedlist

What's the preferred way to insert a bulleted list into a Google Doc?


I'm trying to get familiar with Google Apps Script in a Google doc and want to be able to insert a bulleted list with various levels of nesting. I thought I was using body.insertListItem correctly, but what's odd is that when I add subsequent list item, it seems to mess up the nesting levels and glyphs of previously inserted items.

For example, here's my sample code:

function myFunction() {
  var doc = DocumentApp.getActiveDocument()
  var body = doc.getBody()
  var cursor = doc.getCursor()
  
  var element = body.insertParagraph(0, "hello world")
  element.setHeading(DocumentApp.ParagraphHeading.HEADING1)
  var ixElement = body.getChildIndex(element)
  var listItem = body.insertListItem(ixElement+1, "List")
  listItem.setNestingLevel(0)
  listItem.setGlyphType(DocumentApp.GlyphType.BULLET)
  var listItem2 = body.insertListItem(ixElement+2, "List Item")
  listItem2.setNestingLevel(1)
  listItem2.setGlyphType(DocumentApp.GlyphType.HOLLOW_BULLET)
  var listItem3 = body.insertListItem(ixElement+3, "2nd List Item")
  listItem3.setNestingLevel(1)
  listItem3.setGlyphType(DocumentApp.GlyphType.HOLLOW_BULLET)  
  var listItem4 = body.insertListItem(ixElement+4, "2x nested list Item")
  listItem4.setNestingLevel(2)
  listItem4.setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET)    
  //listItem.setGlyphType(DocumentApp.GlyphType.BULLET)
}

The problem is that is that the only call to .setGlyphType that "sticks" is the last one that's called. Each previous bullet gets changed.

Expected:

expected image

Actual:

actual image

You can see in the image for the actual results that the first list item should have been a bullet, but was changed to a number. (If I call listItem.setGlyphType(DocumentApp.GlyphType.BULLET) again it will change back to a bullet). This makes me think I may be going about this the wrong way. Is there a better way to insert listItem elements into a Google Doc with Apps Script?


Solution

  • Issue:

    Solutions:

    //@OnlyCurrentDoc
    function fixedMyFunction2() {
      'use strict';
      var doc = DocumentApp.getActiveDocument();
      var body = doc.getBody();
    
      var element = body.insertParagraph(0, 'hello world');
      element.setHeading(DocumentApp.ParagraphHeading.HEADING1);
      var ixElement = body.getChildIndex(element);
      var listItem = body.insertListItem(ixElement + 1, 'List');
      listItem.setNestingLevel(0);
      listItem.setGlyphType(DocumentApp.GlyphType.BULLET);
    
      var listItem2 = listItem
        .copy()
        .setNestingLevel(1)
        .setGlyphType(DocumentApp.GlyphType.HOLLOW_BULLET);
      listItem2.setText('List Item');
      body.insertListItem(ixElement + 2, listItem2);
    
      var listItem3 = listItem2.copy();
      listItem3.setText('2nd ListItem');
      body.insertListItem(ixElement + 3, listItem3);
    
      var listItem4 = listItem2
        .copy()
        .setNestingLevel(2)
        .setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET);
      listItem4.setText('2x nested listItem');
      body.insertListItem(ixElement + 4, listItem4);
    }
    
    //@OnlyCurrentDoc
    function fixedMyFunction() {
      'use strict';
      var doc = DocumentApp.getActiveDocument();
      var body = doc.getBody();
    
      var element = body.insertParagraph(0, 'hello world');
      element.setHeading(DocumentApp.ParagraphHeading.HEADING1);
      var ixElement = body.getChildIndex(element);
      var listItem = body.insertListItem(ixElement + 1, 'List');
      listItem.setNestingLevel(0);
    
      var listItem2 = body.insertListItem(ixElement + 2, 'List Item');
      listItem2.setNestingLevel(1);
      var listItem3 = body.insertListItem(ixElement + 3, '2nd List Item');
      listItem3.setNestingLevel(1);
    
      var listItem4 = body.insertListItem(ixElement + 4, '2x nested list Item');
      listItem4.setNestingLevel(2);
    
      //Setglyphs at last
      listItem4.setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET);
      listItem3.setGlyphType(DocumentApp.GlyphType.HOLLOW_BULLET);
      listItem.setGlyphType(DocumentApp.GlyphType.BULLET);
    }