OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
687 stars 94 forks source link

Issue with insertText in Content Controls #2183

Closed mynameismon closed 2 years ago

mynameismon commented 3 years ago

[Related: #1094]

Funnily, I am encountering this exact issue on Word 2019 (Windows). Word Version: Microsoft® Word 2019 MSO (Version 2111 Build 16.0.14609.20000) 64-bit

The code can be found here: https://gist.github.com/mynameismon/ef7ec86842c7eb2f3290c9af3d09132d

To reproduce:

Everything works fine until the insertion of text.

isabela-dominguez commented 3 years ago

Thank you for reporting this issue @mynameismon! Connecting you with @RuoyingLiang to help investigate this issue.

Shujee commented 2 years ago

Any update about this? I'm getting this behavior on Windows 11 and Word 2019 MSO (Version 2201 Build 16.0.14827.20028) 32-bit. insertText simply doesn't insert anything in the ContentControl. No exception either.

yihuax-msft commented 2 years ago

@mynameismon What is the expected behavior? What are the results you saw on your computer? I am not clear what is the problem you encountered....

When you said "Select" content control, did you mean to select all text INSIDE the content control, or you meant to select also the control control's start and end tags? (click ribbon's Developer tab and then click "Design Mode".)

Also, when you said "empty" content control, did you mean a content control with "Click or tap here to enter text." in it, or really empty with nothing in it (no prompt text)?

Thanks.

mynameismon commented 2 years ago

Hi,

It has been a while since I have touched this, but I can certainly answer your questions from my memory.

What is the expected behavior? What are the results you saw on your computer? I am not clear what is the problem you encountered Expected Behaviour: Text is inserted in the content controls on calling wordCountContentControls.insertText() Results: Nothing happens. By nothing I mean, no text is inserted.

When you said "Select" content control, did you mean to select all text INSIDE the content control, or you meant to select also the control control's start and end tags? All the text. However, that is not where the problem lies, since the content control is being identified fine (evident by console.log()ing and inspecting the output. The problem lies in the inserting of text alone

Also, when you said "empty" content control, did you mean a content control with "Click or tap here to enter text." in it, or really empty with nothing in it (no prompt text)? I believe the first, although I am a bit fuzzy with the details.

I am attaching a sample document, that should be helpful in replicating the issue: Testing document.docx

yihuax-msft commented 2 years ago

@mynameismon, Let me check why the insertText API is not called. In the meantime, you may use the following code to get the selected content control:

var sel = context.document.getSelection();
var myCCs = sel.contentControls;
var parentCC = sel.parentContentControlOrNullObject;
myCCs.load();
parentCC.load();
await context.sync();
if (myCCs.items.length > 0)
  contentControlVar = myCCs.items[0];
else
  contentControlVar = parentCC;
yihuax-msft commented 2 years ago

Hi, on my machine the following code works (I removed "globalThis" since it is not supported on my machine). Just compare it with your original code. Thanks!

let wcUpdate = setInterval(() => {}, 1000); var wordCountContentControls; var essayContentControls;

$("#updateWordCount").click(() => { wcUpdate = setInterval(updateWordCount, 1000); });

$("#stopUpdateWordCount").click(() => { clearInterval(wcUpdate); });

$("#getWcContentControl").click(async () => { await getContentControls().then((value) => { wordCountContentControls = value; }); });

$("#getEssayContentControl").click(async () => { await getContentControls().then((value) => { essayContentControls = value; }); });

$("#stop").click(() => stop());

async function updateWordCount() { await Word.run(wordCountContentControls, async (context) => { essayContentControls.load("text"); wordCountContentControls.load("text"); await context.sync(); console.log(wordCountContentControls.text); let body = essayContentControls.text; let numWords = wordCount(body); wordCountContentControls.insertText(numWords.toString() + " Words", Word.InsertLocation.replace); await context.sync().then(() => console.log("Done")); }); }

function wordCount(body) { body = body.replace(/\r\n|\r|\n/g, " "); //In cases where you have "...last word.First word..." //it doesn't count the two words around the period. //so I replace all punctuation with a space let punctuationless = body.replace(/[.,\/#!$%\^&*;:{}=-_`~()"?“”]/g, " "); //Finally, trim it down to single spaces (not sure this even matters) let finalString = punctuationless.replace(/\s{2,}/g, " "); //Actually count it var count = finalString.trim().split(/\s+/).length; return count; }

async function getContentControls() { var contentControlVar; await Word.run(async (context) => { var myCCs = context.document.getSelection().contentControls; myCCs.load(); await context.sync(); contentControlVar = myCCs.items[0]; console.log(contentControlVar); context.trackedObjects.add(contentControlVar); return contentControlVar; }).then((value) => { contentControlVar = value; }); console.log(contentControlVar); return contentControlVar; }

async function stop() { clearInterval(wcUpdate); }

mynameismon commented 2 years ago

Works. Thanks!