Angular PDF Viewer
Version - 24.2.0Angular - 17.3.12

Custom Find Algorithm

This is a very advanced usecase.

Since Version 21.3.0

If you want to implement your own find algorithm, define a class implementing the find controller and pass it to the attribute pdfDefaultOptions.findController before opening the PDF file.

To get started, copy the files pdf_find_controller.js, ui_utils.js, and pdf_find_utils.js from the source code of this showcase to your project and extend your own find controller from the class PDFFindController.

HTML

<ngx-extended-pdf-viewer
  src="/assets/pdfs/Portugues-para-principiantes-1538054164.pdf"
  [textLayer]="true"
  [showFindButton]="false"
  (updateFindMatchesCount)="onUpdateFindMatchesCount($event)"
  (pdfLoaded)="pdfLoaded()">
</ngx-extended-pdf-viewer>

TypeScript

Component

@Component({
standalone: false, ...})
export class CustomFindComponent {

  constructor() {
    pdfDefaultOptions.findController = MyCustomFindController;
  }
}

Custom Find Controller Class

import { PDFFindController } from './pdf_find_controller';

export class MyCustomFindController extends PDFFindController {
  constructor({ linkService, eventBus, updateMatchesCountOnProgress = true, pageViewMode }: any) {
    super({ linkService, eventBus, updateMatchesCountOnProgress, pageViewMode });
    console.log('MyFindController constructor');
  }
}

Before Version 21.3.0

Demonstration of customizing the find functionality. This works by overriding the default find functionality of the pdf.js viewer, adding support for regex search in this example. A more complete implementation would provide a custom find bar.

HTML

<ngx-extended-pdf-viewer
  src="/assets/pdfs/Portugues-para-principiantes-1538054164.pdf"
  [textLayer]="true"
  [showFindButton]="false"
  (updateFindMatchesCount)="onUpdateFindMatchesCount($event)"
  (pdfLoaded)="pdfLoaded()">
</ngx-extended-pdf-viewer>

TypeScript

interface CustomFindOptions extends FindOptions {
  matchRegex: boolean;
}

@Component({
standalone: false, ...})
export class CustomFindComponent {
  searchtext = '(?<=\\s)([A-z]+ough)';
  findOptions: CustomFindOptions = {
    highlightAll: true,
    matchCase: false,
    wholeWords: false,
    matchDiacritics: false,
    matchRegex: true
  };


  constructor(notificationService: PDFNotificationService) {
    effect(() => this.pdfViewerApplication = notificationService.onPDFJSInitSignal());
  }

  // Override the find feature to support regex after the PDF is loaded
  pdfLoaded() {
    this.overrideFindFeature();
  }

  // Optional: Restore the original find feature
  ngOnDestroy() {
    this.restoreFindFeature();
  }

  findRegex() {
    this.dispatchFind('find');
  }

  findNext(): void {
    this.dispatchFind('again', false);
  }

  findPrevious(): void {
    this.dispatchFind('again', true);
  }

  /**
   * Override the find feature to support regex
   */
  private overrideFindFeature() {
    const findController = this.pdfViewerApplication.findController as any;

    const originalConvertToRegExpString = findController._convertToRegExpString;
    findController._convertToRegExpString = (query: string, ...args: any[]) => {
      const { matchRegex } = findController.state;

      // If not matchRegex, call the original method
      if (!matchRegex) return originalConvertToRegExpString.call(findController, query, ...args);

      // If matchRegex, return the query as is
      return [false, query];
    };
  }

  // Need to use dispatch directly
  private dispatchFind(type: string, findPrevious = false): void {
    this.pdfViewerApplication.eventBus.dispatch('find', {
      ...this.findOptions,
      query: this.searchtext,
      type,
      findPrevious,
      source: undefined
    });
  }
}