Reputation: 370
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
Reputation: 1068
A short version:
const doc = DocumentApp.getActiveDocument();
const cursor = doc.getCursor();
doc.setCursor(doc.newPosition(cursor.getElement(), cursor.getOffset() + 1));
Upvotes: 0
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
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