Articles in this section
Category / Section

Search Icon and Exclude Match in Search Results in Angular PDF Viewer.

10 mins read

Customizing Search Icon and Excluding Exact Matches from search results in PDF Viewer

Description:

This article demonstrates how to customize the search icon in the toolbar and search box to exclude exact matches from the search results in the Angular PDF Viewer.

Solution:

To achieve this, the customToolbar item is used to include a custom “Find Text” button in the toolbar, and a custom search box is implemented. This allows you to tailor the search functionality, providing the ability to exclude exact matches and enhance the search experience.

The customized search box includes the following features:

Search Input: Enter text to search in the PDF document.
Previous/Next Buttons: Navigate through search occurrences.
Case-Sensitive Search: Enable or disable match-case search with a checkbox.
Clear Search: Clear search input and results.
Toggle Search Box: Show or hide the custom search box from the toolbar button.
The search functionality is powered by the textSearchModule of the PDF Viewer, and the search logic is implemented in the component.

Code Snippets:

app.component.html

The HTML includes the PDF Viewer and a custom search box that can be toggled from the toolbar.

<ejs-pdfviewer
      #pdfviewer
      id="pdfViewer"
      [documentPath]="document"
      [resourceUrl]="resource"
      [toolbarSettings]="toolbarSettings"
      (toolbarClick)="toolbarClick($event)"
      style="height:640px;display:block"
    ></ejs-pdfviewer>
  <div id="textSearchToolbar" [style.display]="'none'">
    <div
      class="e-pv-search-bar"
      id="container_search_box"
      [style.top]="'200px'"
      [style.right]="'0px'"
      [style.height]="'70px'"
      [style.width]="'300px'"
    >
      <div class="e-pv-search-bar-elements" id="container_search_box_elements">
        <div
          class="e-input-group e-pv-search-input"
          id="container_search_input_container"
        >
          <input
            class="e-input"
            id="container_search_input"
            type="text"
            placeholder="Find in document"
            (keypress)="searchInputKeypressed($event)"
            (input)="inputChange()"
          />
          <span
            class="e-input-group-icon e-input-search-group-icon e-icons e-search"
            id="container_search_box-icon"
            style="top: 4px;"
            (click)="initiateTextSearch()"
          ></span>
          <span
            class="e-input-group-icon e-input-search-group-icon e-icons e-close"
            id="container_close_search_box-icon"
            [style.display]="'none'"
            style="top: 4px;"
            (click)="clearTextSearch()"
          ></span>
        </div>
        <button
          class="e-btn e-icon-btn e-pv-search-btn e-icons e-chevron-left"
          id="container_prev_occurrence"
          (click)="previousTextSearch()"
          type="button"
          [disabled]="true"
          aria-label="Previous Search text"
        ></button>
        <button
          class="e-btn e-icon-btn e-pv-search-btn e-icons e-chevron-right"
          id="container_next_occurrence"
          type="button"
          (click)="nextTextSearch()"
          [disabled]="true"
          aria-label="Next Search text"
        ></button>
      </div>
      <div
        class="e-pv-match-case-container"
        id="container_match_case_container"
      >
        <div class="e-checkbox-wrapper e-wrapper e-pv-match-case">
          <label for="container_match_case">
            <input
              id="container_match_case"
              type="checkbox"
              class="e-control e-checkbox e-lib"
              (click)="checkBoxChanged($event)"
            />
            <span class="e-ripple-container" data-ripple="true"></span>
            <span id="checkboxSpan" class="e-icons e-frame"></span>
            <span class="e-label">Match case</span>
          </label>
        </div>
      </div>
    </div>
  </div>
app.component.ts:

The TypeScript file manages the toolbar settings, search functionality, and custom logic for toggling the search box, performing searches, and handling match-case functionality.

public matchCase = false;
  public searchActive = false;
  public toolItem4: CustomToolbarItemModel = {
    prefixIcon: 'e-icons e-search',
    tooltipText: 'Find Text',
    id: 'find_text',
    align: 'Right',
  };
  public toolbarSettings = {
    showTooltip: true,
    toolbarItems: [
      'OpenOption',
      'PageNavigationTool',
      'MagnificationTool',
      'PanTool',
      'SelectionTool',
      this.toolItem4,
      'PrintOption',
      'DownloadOption',
      'UndoRedoTool',
      'AnnotationEditTool',
      'FormDesignerEditTool',
      'CommentTool',
      'SubmitForm',
    ],
  };
  public searchInputKeypressed(event: KeyboardEvent): void {
    if (event.key === 'Enter') {
      this.initiateTextSearch();
    }
  }
  public searchText: string = '';
  public prevMatchCase = false;
  public initiateTextSearch(): void {
    const textsearchPrevElement = document.getElementById(
      'container_prev_occurrence'
    ) as HTMLButtonElement;
    const textsearchNextElement = document.getElementById(
      'container_next_occurrence'
    ) as HTMLButtonElement;
    const textsearchcloseElement = document.getElementById(
      'container_close_search_box-icon'
    ) as HTMLElement;
    const textsearchElement = document.getElementById(
      'container_search_box-icon'
    ) as HTMLElement;

    if (
      textsearchPrevElement &&
      textsearchNextElement &&
      textsearchcloseElement &&
      textsearchElement
    ) {
      textsearchPrevElement.disabled = false;
      textsearchNextElement.disabled = false;
      textsearchcloseElement.style.display = 'block';
      textsearchElement.style.display = 'none';

      if (
        this.searchText !==
          (
            document.getElementById(
              'container_search_input'
            ) as HTMLInputElement
          ).value ||
        this.prevMatchCase !== this.matchCase
      ) {
        this.pdfviewerControl.textSearchModule.cancelTextSearch();
        this.searchText = (
          document.getElementById('container_search_input') as HTMLInputElement
        ).value;
        this.searchActive = true;
        this.pdfviewerControl.textSearchModule.searchText(
          this.searchText,
          this.matchCase
        );
        this.prevMatchCase = this.matchCase;
      } else {
        this.nextTextSearch();
      }
    }
  }
  public nextTextSearch(): void {
    this.pdfviewerControl.textSearchModule.searchNext();
    this.searchActive = true;
  }

  public previousTextSearch(): void {
    this.pdfviewerControl.textSearchModule.searchPrevious();
    this.searchActive = true;
  }

  public checkBoxChanged(event: Event): void {
    const target = event.target as HTMLInputElement;

    if (target.checked) {
      const matchcaseElement = document.getElementById(
        'container_match_case'
      ) as HTMLInputElement;
      if (matchcaseElement) {
        matchcaseElement.checked = true;
      }
      this.matchCase = true;
      const checkboxSpanElement = document.getElementById('checkboxSpan');
      if (checkboxSpanElement) {
        checkboxSpanElement.classList.add('e-check');
      }
    } else {
      this.matchCase = false;
      const checkboxSpanElement = document.getElementById('checkboxSpan');
      if (checkboxSpanElement) {
        checkboxSpanElement.classList.remove('e-check');
      }
    }
  }

  public clearTextSearch(): void {
    const textsearchcloseElement = document.getElementById(
      'container_close_search_box-icon'
    ) as HTMLElement;
    const textsearchElement = document.getElementById(
      'container_search_box-icon'
    ) as HTMLElement;
    textsearchcloseElement.style.display = 'none';
    textsearchElement.style.display = 'block';
    this.pdfviewerControl.textSearchModule.cancelTextSearch();
    const searchTextElement = document.getElementById(
      'container_search_input'
    ) as HTMLInputElement;
    searchTextElement.value = '';
    (
      document.getElementById('container_prev_occurrence') as HTMLButtonElement
    ).disabled = true;
    (
      document.getElementById('container_next_occurrence') as HTMLButtonElement
    ).disabled = true;
  }

  public inputChange(): void {
    this.pdfviewerControl.textSearchModule.clearAllOccurrences();
    this.searchActive = false;
    if (
      (document.getElementById('container_search_input') as HTMLInputElement)
        .value == ''
    ) {
      const textsearchcloseElement = document.getElementById(
        'container_close_search_box-icon'
      ) as HTMLElement;
      const textsearchElement = document.getElementById(
        'container_search_box-icon'
      ) as HTMLElement;
      textsearchcloseElement.style.display = 'none';
      textsearchElement.style.display = 'block';
      (
        document.getElementById(
          'container_prev_occurrence'
        ) as HTMLButtonElement
      ).disabled = true;
      (
        document.getElementById(
          'container_next_occurrence'
        ) as HTMLButtonElement
      ).disabled = true;
    } else {
      (
        document.getElementById(
          'container_prev_occurrence'
        ) as HTMLButtonElement
      ).disabled = false;
      (
        document.getElementById(
          'container_next_occurrence'
        ) as HTMLButtonElement
      ).disabled = false;
    }
  }

  public toolbarClick(args: any): void {
    console.log(args);
    if (args.item && args.item.id === 'find_text') {
      if (
        document.getElementById('textSearchToolbar').style.display === 'block'
      ) {
        document.getElementById('textSearchToolbar').style.display = 'none';
      } else {
        document.getElementById('textSearchToolbar').style.display = 'block';
      }
    }
  }
Sample Link:

You can find the full sample in our GitHub repository.

Conclusion:

I hope you enjoyed learning about how to search icon and exclude match in search results in Angular PDF Viewer.

You can refer to Angular PDF feature tour page to know about its other groundbreaking feature representations and documentation , and how to quickly get started for configuration specifications.

You can also explore our Angular PDF Viewer example to understand how to create and manipulate data.

For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our other controls.

If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please  to leave a comment
Access denied
Access denied