Getting empty array on contentControls officejs

71 Views Asked by At
    Word.run( async (context) => {
    var searchResults = context.document.body.search('moslim');
    context.load(searchResults);
    return context.sync().then(async function () {
      if (searchResults.items.length > 0) {
        // Get the first search result
        var range = searchResults.items[0].getRange();
        // range.clear();
        // Insert a content control around the search result
        var contentControl = range.insertContentControl();
        // Set the tag of the content control
        contentControl.tag = 'your tag';
        contentControl.insertText(searchResults.items[0].text.toString(), 'Replace'); 

        // Load the content control
        context.load(contentControl);
        await context.sync()

        var getcontentControl  = range.contentControls

        context.load(getcontentControl)
        await context.sync()

        console.log(getcontentControl.items)
      }
    });
});

last console.log gives empty array but contentcontrol has been added the ms word document.

Can anyone help on this what I did wrong?

1

There are 1 best solutions below

0
On

I don't think you did anything "wrong" It's just that, despite the fact that you are calling a method called insertContentControl on your Range object, office-js surrounds the range with the control (at least in the case you mention) in such a way that it is not actually added to the range.

The question is what you are actually trying to achieve and how to do that. (It wasn't obvious from the Question as it stands).

If you did the equivalent thing in VBA to your found text, it might be

myrange.ContentControls.Add wdContentControlRichText

In that case, in VBA the content control is in myrange, i.e.

myrange.ContentControls.Count

returns 1. But it wouldn't be in myrange if myrange did not "cover" any characters (i.e. myrange.Start=myrange.End )

I made a simple modification to your office-js code to select the range it found. I also commented out the code that puts text in the control

var contentControl = range.insertContentControl();
range.select();
// Set the tag of the content control
contentControl.tag = 'your tag';
//contentControl.insertText(searchResults.items[0].text.toString(), 'Replace');

If I run your example code with those changes, it's quite easy to find out where the VBA WOrd object model thinks the control and the range are:

Sub rangeandccinfo()
Debug.Print ActiveDocument.ContentControls(1).Range.Start, ActiveDocument.ContentControls(1).Range.End
'In office-js we set by using the Range. So they should really be the same (except maybe we shouldn't
'expect office-js to behave the same as the traditional object model.
Debug.Print Selection.Start, Selection.End
Debug.Print Selection.Range.ContentControls.count
Debug.Print Selection.Range.Information(wdInContentControl)
End Sub

In my experiment, the results are like this

3             9 
3             9 
0 

True

But if I just select the same word manually and insert the CC using VBA like this:

Sub ccrange()
Dim r As Range
Debug.Print Selection.Start, Selection.End
Set r = Selection.Range
'should be the same
Debug.Print r.Start, r.End
r.ContentControls.Add wdContentControlRichText
Debug.Print r.Start, r.End
r.Select
Set r = Nothing
End Sub

then run the rangeandccinfo() Sub, I see this:

 3             9 
 2             9 
 1 
True

i.e. in office-js, it looks as if the range and the range of the Content Control have the same Start and End, whereas in VBA, the Range starts one character before the Range of the Content Control, and that seems to be what make the VBA count of COntent COntrols in the Range 1 rather than 0.

If you actually click at the beginning of the text in a Content Control and click the left arrow button (in a document with left-to-right text) you will see that the insertion point does not appear to move. And yet its Range does change.

So it's at least partly an implementation choice how to do this. Personally, I have found it quite difficult to work with the way VBA does it (its difficult to work out what's inside what). It's quite possible that the office-js team encountered a similar problem and just decided to do it a way that made more sense to them.