Clicking on highlighted word should draw a box annotation around it

Hey there!

Sorry for the delay, this one took me a little while to figure out.

To get this functionality you need to use our more advanced search API, since the searchText API just creates non-selectable highlights.

Here is the code I ended up writing to accomplish this use case:

Webviewer({
  ...options
}, document.getElementById('viewer')).then(instance => {

  const { docViewer, CoreControls, Annotations, annotManager } = instance;

  docViewer.on('documentLoaded', () => {
    const searchText = 'YOUR_SEARCH_TEXT';
    const mode = CoreControls.Search.Mode.PAGE_STOP | CoreControls.Search.Mode.HIGHLIGHT;
    const searchOptions = {
      fullSearch: true, // search full document
      onResult: result => {
        if (result.resultCode === CoreControls.Search.ResultCode.FOUND) {
          const textQuad = result.quads[0].getPoints();
          const annot = new Annotations.TextHighlightAnnotation();

          annot.X = textQuad.x1;
          annot.Width = textQuad.x2 - textQuad.x1;

          annot.Y = textQuad.y3;
          annot.Height = textQuad.y1 - textQuad.y3;

          annot.FillColor = new Annotations.Color(0, 0, 255, 0.5);
          annot.StrokeColor = new Annotations.Color(0, 0, 255, 0.5);

          annot.Quads = [textQuad];

          // add custom property so we can check in annotationSelected function
          annot.IsCustomSearch = true;

          annotManager.addAnnotation(annot);
          annotManager.drawAnnotationsFromList([annot])
        }
      }
    };

    // start the search
    docViewer.textSearchInit(searchText, mode, searchOptions);
  });

  // Listen for when our search annots are selected
  annotManager.on('annotationSelected', (annots) => {
    if (!annots) return;
    annots.forEach(annot => {

      // check that our custom 'IsCustomSearch' property is set
      if (annot instanceof Annotations.TextHighlightAnnotation && annot.IsCustomSearch) {
        const { X, Y, Width, Height } = annot;
        
        // Here you can use X, Y, Width, Height 
        // to create a new Rectangle Annotation! 
 
      }

    })
  })
});

What I am doing here is using the textSearchInit function, which gives us actual positions of the search results in the callback function.

Using those positions, I create highlight annotations. On each of these highlight annots, I add a custom property called “IsCustomSearch” (this could be named whatever you want). I do this so that in our annotationSelected handler, we can check if one of our custom highlight annots was selected.

In the annotationSelected handler, I check if the selected annotation is one of our custom highlights. If it is, I can use the position of that annotation to create a new rectangle annotation as per your spec.

Here are some APIs that might be useful for you as well.

  • Rectangle Annotation
  • Get all annotations on doc - This might be useful if you want to delete all your custom highlights at some point. You can loop over these, get the ones with our custom IsCustomSearch property, and delete them
  • Delete annotatation This will be useful for deleting the highlight and replacing it with the new rectangle annotation. Will also be useful for the previous point.

I hope this helps! Let me know if there are any more questions.

Thanks,
Logan