Is it possible to use textSearchInit to search for a list of terms?

WebViewer Version: 7.3.3

Do you have an issue with a specific file(s)?
No

Can you reproduce using one of our samples or online demos?
Yes for a single search term works fine. But if I iterate over an array of search terms only the results for the last element is returned.
Used eg from https://www.pdftron.com/documentation/web/guides/advance-text-search/

Is it possible to run textSearchInit multiple times and get all the results?

Are you using the WebViewer server?
No

Does the issue only happen on certain browsers?
No

Is your issue related to a front-end framework?
React

Is your issue related to annotations?
No

Please give a brief summary of your issue:
Unable to run docViewer.textSearchinit over an array of search terms

Please provide a link to a minimal sample where the issue is reproducible:
Using the following git hub sample project as a start point

I replaced the useEffect with the following useEffect. The console output only had results for “scratch”

useEffect(() => {

WebViewer(

  {

    path: "/webviewer/lib",

    initialDoc: "/files/PDFTRON_about.pdf",

  },

  viewer.current

).then((instance) => {

  const { docViewer, CoreControls } = instance;

  docViewer.on("documentLoaded", () => {

    const searchTextList = ["mistake", "scratch"];

    const mode =

      CoreControls.Search.Mode.PAGE_STOP |

      CoreControls.Search.Mode.HIGHLIGHT |

      CoreControls.Search.Mode.WHOLE_WORD;

    searchTextList.forEach((s) => {

      const searchOptions = {

        fullSearch: true,

        onResult: (result) => {

          if (result.resultCode === CoreControls.Search.ResultCode.FOUND) {

            console.log(result);

          }

        },

      };

      docViewer.textSearchInit(s, mode, searchOptions);

    });

  });

});

}, []);

Hello, I’m Ron, an automated tech support bot :robot:

While you wait for one of our customer support representatives to get back to you, please check out some of these documentation pages:

Guides:APIs:Forums:

Hi,

Thank you for the sample code. Currently calling “textSearchInit” again will cancel the current search and start searching with the new search term. You can use the “CoreControls.Search.Mode.REGEX” and do a regex search (can search for “mistake|scratch”). Please let me know if that works for you or if you have any other questions

Best Regards,

Andrew Yip
Software Developer
PDFTron Systems, Inc.

1 Like

Hi Andrew,

That work brilliantly! Thank you.
For the time being this seems to do the job, not entirely sure how performant it would be for larger set of search terms. Will probably need to look at a server side solution for that if the need arises.

Thanks again.

Regards,
Fabio

Hi !
I have list of regex terms. textSearchInit cancel the current search and start searching with the new search term. How can I solve this problem ?

Hi,

Sadly there isn’t way to solve the issue with search cancelling when a new one start. By design WebViewer will stop the current search and start a new search with the updated search terms. Currently our WebViewer UI would start searching as user type inputs and cancel the previous search as new characters are enter (so the current behavior is influence by the UI design).

Changing the current behavior is possible but is not trivial. Also performance won’t be good since it’ll be performing multiple searches at once, searching multiple terms using regex would be faster. It’ll likely involve adding a “cancel search API” (canceling pervious searches and doing a regex search would be faster in a lot of cases). We could add this if there is enough demand. I’ll talk to our product manager about this and see if we can get this added to our backlog.

Best Regards,

Andrew Yip
Software Developer
PDFTron Systems, Inc.

One other potential option would be to call textSearchInit multiple times and keep the results in a list so that when the new search happens you can basically immediately add them back. For example:

const { Core } = instance;
const { documentViewer } = Core;

instance.UI.openElement('searchPanel');

const results = [];

const performSearch = (searchTerm) => {
  return new Promise(resolve => {
    const mode = Core.Search.Mode.PAGE_STOP | Core.Search.Mode.HIGHLIGHT | Core.Search.Mode.AMBIENT_STRING | Core.Search.Mode.REGEX;
    const searchOptions = {
      fullSearch: true,
      onResult: (result) => {
        results.push(result);
        documentViewer.displayAdditionalSearchResult(result);
      },
      onDocumentEnd: () => {
        resolve();
      }
    };
    documentViewer.textSearchInit(searchTerm, mode, searchOptions);

    documentViewer.displayAdditionalSearchResults(results);
  });
};

documentViewer.addEventListener('documentLoaded', async () => {
  await performSearch(searchTerm1);
  await performSearch(searchTerm2);
  await performSearch(searchTerm3);
});

Note that the performance of a single search will likely be better than this approach because it will only search through the document a single time, while this approach will search through multiple times. So if you’re able to combine multiple regexes into a single combined regex that may be another option.