STEM FabLab
STEM FabLab

Reputation: 370

How can I move the cursor to the end of the inserted text with Google Apps Script for Docs?

I'm writing an add on for Google Docs to allow users to choose from lists of canned text samples to insert into their document. I want the text inserted like this:

1st_text_insertion

2nd_text_insertion

3rd_text_insertion

However, my code results in the following:

3rd_text_insertion

2nd_text_insertion

1st_text_insertion

The reverse ordering occurs because the cursor position remains in the same place rather than updating to the end of the last text insertion.

Here's the code I'm using:

function insertText(text) {
  var doc = DocumentApp.getActiveDocument();
  var cursor = doc.getCursor();
  newPosition = cursor.insertText(text + '\r');
  doc.setCursor(newPosition);
}

The code needs to be flexible enough to insert text wherever the cursor is placed and then add new entries following a return character. For example, if the user placed their cursor on a blank line between existing text items B and C, the inserted text should appear on new lines between items B and C.

Example before text insertion:

existing_text_A

existing_text_B

existing_text_C

Desired output after text insertion:

existing_text_A

existing_text_B

1st_text_insertion

2nd_text_insertion

3rd_text_insertion

existing_text_C

I've tried several approaches, such as using appendText or getNextSibling, but they don't produce the desired output. Thanks for any help!

Upvotes: 5

Views: 2311

Answers (3)

gaspar
gaspar

Reputation: 1068

A short version:

const doc = DocumentApp.getActiveDocument();
const cursor = doc.getCursor();
doc.setCursor(doc.newPosition(cursor.getElement(), cursor.getOffset() + 1));

Upvotes: 0

Cooper
Cooper

Reputation: 64032

This will put the cursor at the end of the inserted text.

function insertTextAtCursor(txt){
  var doc=DocumentApp.getActiveDocument();
  var body=doc.getBody();
  var t=doc.getCursor().insertText('\n' + txt);
  var txtEl=doc.getCursor().getElement();
  var txtOff=doc.getCursor().getOffset();
  var pos=doc.newPosition(txtEl, txtOff + 1);//I can't actually explain this.  I figured out based upon the error I was getting in the console log
  doc.setCursor(pos);
}

Upvotes: 4

STEM FabLab
STEM FabLab

Reputation: 370

Cooper, thank you! Your answer worked.

I found I needed to handle special cases with paragraphs and list items. I expanded on your code and I'm sharing this solution to help others.

function insertText(txt){
// Summary: Locates the user's cursor, then inserts new text as either a 
  // new paragraph or a new list item, and then updates the cursor position 
  // after the inserted text.
  var doc=DocumentApp.getActiveDocument();
  var txtPos=doc.getCursor();
  var txtElement=txtPos.getElement();
  var txtElementType=txtElement.getType();
  parentElement = txtElement.getParent();
  childIndex = parentElement.getChildIndex(txtElement);
  // Determines if text is within a paragraph and adds a new paragraph
  if (txtElementType == DocumentApp.ElementType.PARAGRAPH) {
    var t = parentElement.insertParagraph(childIndex + 0,txt);

  // Determines if text is within a list item and adds a new list item
  } else if (txtElementType == DocumentApp.ElementType.LIST_ITEM) {
    txtGlyphType = txtElement.getGlyphType();
    var t = parentElement.insertListItem(childIndex + 0, txt).setGlyphType(txtGlyphType);

  // Determines if text is within a text element (e.g., within a multi-word block of text)
  // and then determines whether the text element is within a paragraph or a list item.
  } else if (txtElementType == DocumentApp.ElementType.TEXT) {
    parentElementType = parentElement.getType();
    parentparentElement = parentElement.getParent();
    parentparentIndex = parentparentElement.getChildIndex(parentElement);

    // Adds a new paragraph if text element is within a paragraph 
    if (parentElementType == DocumentApp.ElementType.PARAGRAPH) {
    var t = parentparentElement.insertParagraph(parentparentIndex + 0,txt); 

      // Adds a new list item if text element is within a list item
    } else if (parentElementType == DocumentApp.ElementType.LIST_ITEM) {
      parentGlyphType = parentElement.getGlyphType();
      var t = parentparentElement.insertListItem(parentparentIndex + 0, txt).setGlyphType(parentGlyphType);
    }
  }
  // Updates the position of the cursor to follow the inserted text
  newPosition = parentElement.getChild(childIndex + 1);
  var pos = doc.newPosition(newPosition, 0);
  doc.setCursor(pos);
}

Upvotes: 0

Related Questions