liz li
liz li

Reputation: 15

How to loop through a RangeCollection in Word JS API?

I want to add a Find function in my Word Add-in. By clicking a button, the Word will scroll to the first place of the word need to be searched, and by clicking again, the Word will scroll to the next place. I figured out how to find the first one, but I can't loop through the RangeCollection of the search results of the word. I am looking for some functions similar to getNext()

Below is the code to find first "and". It works:

  async function scroll() {
    await Word.run(async (context) => {
      context.document.body.search("and", { matchWholeWord: true, matchCase: false }).getFirst().select();
      await context.sync() 
    }
  )}

However, if I want to find the second or more, I can't do this:

async function scroll() {
await Word.run(async (context) => {
  context.document.body.search("and", { matchWholeWord: true, matchCase: false }).getFirst().getNext().select();
  await context.sync() 
}  )}

I read the document and there is no getNext() for RangeCollection. Hope somebody knows how to work around it. Thank you!

Upvotes: 0

Views: 353

Answers (1)

chiz-ms
chiz-ms

Reputation: 136

There are a few workarounds.

Solution 1

Load RangeCollection.items and record the index. Example:

var index = 0;

async function selectNext(...) {
  ...

  var ranges = context.document.body.search(...);
  ranges.load('items');
  await context.sync();

  if (index >= ranges.items.length) {
    index = 0;
  }

  ranges.items[index++].select();
  await context.sync();

  ...
}

This solution respects the index, but not the current selection position. So if you prefer to search downward instead of searching the next, here's solution 2.

Solution 2

Load RangeCollection.items and call Range.compareLocationWith. Example:

var ranges = context.document.body.search(...);
ranges.load('items');
await context.sync();

var selection = context.document.getSelection();
var compareResults = ranges.items.map(range => range.compareLocationWith(selection));
await context.sync();

for(var index in compareResults) {
  if (compareResults[index].value == 'After') {
    ranges.items[index].select();
    await context.sync();
    break;
  }
}

Of course you would need additional code and polish it to make it a real product, but these are the rough ideas. Please see if they work for you.

Upvotes: 1

Related Questions