find Method

Summary

Searches the pages of a document to find matches to the provided text options.

Syntax
TypeScript
JavaScript
DocumentViewerText.prototype.find = function( 
   options, 
   resultsHandler 
) 

Parameters

options

An instance of DocumentViewerFindText containing options for bounds, starting location, matching options, and post-result actions.

resultsHandler

A callback function of type DocumentViewerFindTextResultsHandler that will be called with the results when the asynchronous find text operation completes. If no results are found, the resultsHandler parameter will be null.

Remarks

(Note: As of version 19.0.0.49, this method has an updated function signature and internal behavior. See "History" for more information. The below remarks apply to versions 19.0.0.49 and above.)

Find searches the pages of a Document to find matches to the search text. Options can be passed via DocumentViewerFindText, which allows for the specification of bounds, starting location, matching options, rendering, and selection.

In JavaScript, Find is an asynchronous operation and takes a callback parameter of type DocumentViewerFindTextResultsHandler. The first parameter of this callback is the array of DocumentViewerMultiLineTextItem, one for each match. If no matches are found, null is returned instead of an empty array.

Find will report its progress via the DocumentViewer.Operation event with the DocumentViewerOperationEventArgs.Operation property set to DocumentViewerOperation.FindText. Find will send the results of each page as it searches, and sends all results at the conclusion of the operation. Setting DocumentViewerOperationEventArgs.Abort to true will cancel the operation, but not render any of the results (even if DocumentViewerFindText.RenderResults is true).

If a page’s DocumentPageText has not been retrieved when the page is being searched, Find may retrieve the DocumentPageText data for that page based on the value of AutoGetText. If no DocumentPageText is found, the page will return null as the result for searches on that page.

Search Options

DocumentViewerFindText.BeginPosition and DocumentViewerFindText.EndPosition set the bounds and direction of the search. The find text operation will always search in the direction of DocumentViewerFindText.BeginPosition to DocumentViewerFindText.EndPosition, even if DocumentViewerFindText.EndPosition is a lower page number and/or character index. Switching these two properties will change the direction of search.

By default, DocumentViewerFindText.Start is set to DocumentViewerFindTextStart.BeginPosition, meaning the search will always begin at DocumentViewerFindText.BeginPosition. Other values for DocumentViewerFindText.Start allow the search to start somewhere between the provided bounds (at a text selection with SelectedTextBegin or SelectedTextEnd or a manually-set position with DocumentViewerFindText.ManualStartPosition), which may then create two sub-searches:

  1. A search from the new starting position to DocumentViewerFindText.EndPosition.

  2. A search from DocumentViewerFindText.BeginPosition through the character before the new starting position.

The second search will only be run if DocumentViewerFindText.FindAll or DocumentViewerFindText.Loop is used.

Results can be automatically highlighted with DocumentViewerFindText.RenderResults and FoundTextFill. It is important to note that subsequent calls will continue to add onto the internal list of results to render, so it is best to clear the render of the last results before each call to Find with ClearRenderedFoundText. All results are returned in order from the start position to the stop position, and the first result can be automatically selected and scrolled to with DocumentViewerFindText.SelectFirstResult.

A short description of each option is provided below:

Option Description

DocumentViewerFindText.BeginPosition

Sets one of the bounds of the search area and helps determine the direction.

DocumentViewerFindText.EndPosition

Sets one of the bounds of the search area and helps determine the direction.

DocumentViewerFindText.Text

Sets the text to match.

DocumentViewerFindText.MatchCase

Indicates whether case matters for search.

DocumentViewerFindText.WholeWordsOnly

Indicates whether DocumentViewerFindText.Text should only match whole words in the page text.

DocumentViewerFindText.FindAll

Indicates whether all matches in the bounds should be searched, or just the first.

DocumentViewerFindText.RenderResults

Sets whether to highlight the results in the DocumentViewer.View.

DocumentViewerFindText.SelectFirstResult

Automatically sets the first in-order result to the selected text.

DocumentViewerFindText.Start

Sets a new starting position for the search inside of the bounds, like a text selection.

DocumentViewerFindText.ManualStartPosition

Allows for a manual character index to be selected based on the value of DocumentViewerFindText.Start.

DocumentViewerFindText.Loop

Indicates whether to wrap back around to search the rest of the bounds not covered before DocumentViewerFindText.Start.

DocumentViewerFindText.Data

Holds extra data.

A copy of the last options supplied to a completed Find is available at LastFindText until ClearLastFindText is called. Unlike previous versions, DocumentViewerFindText does not hold any internal state, so unless something about the document has changed (such as the selected text when using DocumentViewerFindTextStart.InSelection or DocumentViewerFindTextStart.AfterSelection), the same DocumentViewerFindText input instance should return the same set of results.

Multi-line and Multipage Searches

Find will automatically search between lines of text and pages of text, using the concept of "hidden spaces" at line endings. Find will recognize the end of a word/line and allow text on the next line to be matched with a space delimiter. If Find can recognize the end of a paragraph, the next line of text will not be matched.

Some examples for the search term "Hello World":

findtext-multiline-newpage.png
findtext-multiline-newline.png
findtext-multiline-sameline.png

Search Applications

A common scenario when finding text on the page is supporting the "Incremental Find", "Find Next", and "Find Previous" operations. "Find Next" and "Find Previous" are used to continue searching from a match to the next match in a certain direction, while "Incremental Find" attempts to continue matching from _within the current position_, then tries to "Find Next" when the match fails. These operations are possible using the different options in DocumentViewerFindText:

  1. Set the bounds of the search using DocumentViewerFindText.BeginPosition and DocumentViewerFindText.EndPosition as usual. For example, one may search from Page 1, Character 0 to Page 3, Character -1 (end of page). Switching the values in DocumentViewerFindText.BeginPosition and DocumentViewerFindText.EndPosition will change whether the operation is a "Find Next" or "Find Previous".

  2. Set DocumentViewerFindText.Start to one of two options:

    • DocumentViewerFindTextStart.InSelection to continue searching from within the currently selected text. This is ideal for an "Incremental Find" operation where, for example, "L" is already selected from a previous find and you wish to continue matching the remaining text "EADTOOLS" right after it, instead of finding the next or previous match.

    • DocumentViewerFindTextStart.AfterSelection to start the search after the selection ends, in the direction of search. This is useful for "Find Next" or "Find Previous". If no selection exists, DocumentViewerFindText.BeginPosition is used as the start. To continue the example from above, this would search instead for the next "LEADTOOLS" after the "L" already selected.

  3. Ensure DocumentViewerFindText.SelectFirstResult is true so that the first match becomes the new selected item. This is the critical step that makes it possible to keep sending the same DocumentViewerFindText instance but move to the next or previous result.

  4. Optionally, use DocumentViewerFindText.RenderResults and DocumentViewerFindText.FindAll or DocumentViewerFindText.Loop to ensure the entire bounds area is checked and highlighted.

    History

19.0.0.49

19.0.0.49 introduced major changes to the behavior of this method. Prior to version 19.0.0.49, The function signature of the Find method was:

Find was a synchronous method that took three parameters and returned an array of DocumentViewerTextItem that would indicate the next match. Only one match was returned.

DocumentViewerFindText held internal state about the results of the last time it was passed to Find, so passing the same instance to Find could yield different results.

The isFirst parameter indicated whether this find text operation should be treated as the first one. If true, searching would start from the beginning of the document.

The findNext parameter was a boolean switch that was true to indicate searching in the forward direction and false to indicate searching in the backward direction.

Because the method was synchronous, calls to AutoGetText were ignored and pages without a DocumentPageText object were ignored.

When a Find was successful and results were returned, the LastFindText property would be set to the findText parameter that was passed. This would allow for simpler additional searches: because the DocumentViewerFindText object held internal state about the result, subsequent searches with that same instance would search from the last match. "Find Previous" or "Find Next" operations were possible in this manner.

This version of Find did not support "hidden space"/multi-line searches, multipage searches, multiple results with one search, sub-page beginning and ending character positions, or rendering the results with FoundTextFill.

Example

The LEADTOOLS Document Viewer demo uses Find to perform text search operations. Refer to the demo source code for a full example.

In the below example, clicking the example button will find all occurrences of the word "LEAD" by searching the text of the document pages.

TextFind.ts
ViewerInitializer.ts
TextFind.js
ViewerInitializer.js
TextFind.html
examples.css
import { ViewerInitializer } from "../utilities/ViewerInitializer"; 
 
export class TextFindTSExample { 
   public run = () => { 
      new ViewerInitializer(this.textExample); 
   } 
 
   textExample = (documentViewer: lt.Document.Viewer.DocumentViewer) => { 
      const output = document.getElementById('output'); 
      const text = documentViewer.text; 
 
      // Make sure we get the page text if necessary (otherwise, results may be empty!) 
      text.autoGetText = true; 
 
      // We will find all matches of "LEAD", ignoring the case 
      const options = new lt.Document.Viewer.DocumentViewerFindText(); 
 
      // The text 
      options.text = "LEAD"; 
      // Ignore case 
      options.matchCase = false; 
      // Any word that contains the phrase 
      options.wholeWordsOnly = false; 
 
      // Find all results in the bounds, not just the first 
      options.findAll = true; 
 
      // Highlight the results in the View 
      options.renderResults = true; 
      // Optionally, change the highlight color 
      lt.Document.Viewer.DocumentViewerText.foundTextFill = "rgba(255, 255, 0, .4)"; 
 
      // Set direction - this value could be decided from a set of "next" and "previous" buttons 
      const isFindingNext = true; 
      // Set the bounds 
      // We set the bounds as the whole document, but below we can specify to start wherever text is selected 
      // or at the current page 
      const topOfFirstPage = lt.Document.Viewer.DocumentViewerTextPosition.createBeginOfPage(1); 
      const bottomOfLastPage = lt.Document.Viewer.DocumentViewerTextPosition.createEndOfPage(documentViewer.pageCount); 
      if (isFindingNext) { 
         // Make the beginning bound "higher up" the page so we search "down" the page. 
         options.beginPosition = topOfFirstPage; 
         options.endPosition = bottomOfLastPage; 
      } 
      else { 
         // Make the beginning bound "lower down" the page so we search "up" the page. 
         options.beginPosition = bottomOfLastPage; 
         options.endPosition = topOfFirstPage; 
      } 
 
      // Select the first result in the View (automatically scrolls View also) 
      options.selectFirstResult = true; 
 
      if (text.hasAnySelectedText) { 
         // Setting this value to AfterSelection allows us to search forward from the selection, so multiple 
         // uses of this same options object will cycle us through all the matches! 
         // (If no selected text actually exists, search will default to beginPosition.) 
         options.start = lt.Document.Viewer.DocumentViewerFindTextStart.afterSelection; 
      } 
      else { 
         // We could start at the begin position, but it makes more UI sense to start from the user's current page. 
         // Search will loop back around to the begin position - this just changes the starting point and order of results. 
         options.start = lt.Document.Viewer.DocumentViewerFindTextStart.manualPosition; 
         if (isFindingNext) 
            options.manualStartPosition = lt.Document.Viewer.DocumentViewerTextPosition.createBeginOfPage(documentViewer.currentPageNumber); 
         else 
            options.manualStartPosition = lt.Document.Viewer.DocumentViewerTextPosition.createEndOfPage(documentViewer.currentPageNumber); 
      } 
 
      // If we were just looking for the first match, we could use "loop" to loop around 
      // if we found nothing between the start position and the end bound. 
      //options.loop = true; 
 
      // You will likely want to clear the previous highlighted results 
      // on the screen so only our new results will show. 
      text.clearRenderedFoundText(); 
 
      output.innerHTML = "Searching, please wait..."; 
 
      // Search, asynchronously 
      text.find(options, function (results) { 
         const resultsCount = !!results ? results.length : 0; 
 
         let resultText; 
         if (resultsCount > 0) 
            resultText = "Found " + resultsCount + " results for '" + options.text + "'."; 
         else 
            resultText = "No matches found."; 
 
         alert(resultText); 
         output.innerHTML = resultText; 
      }); 
   } 
} 
export class ViewerInitializer { 
   private callback: (viewer: lt.Document.Viewer.DocumentViewer) => void = null; 
 
   constructor(callback?: (viewer: lt.Document.Viewer.DocumentViewer) => void) { 
      this.callback = callback; 
      this.init(); 
   } 
 
   public static showServiceError = (jqXHR, statusText, errorThrown) => { 
      alert('Error returned from service. See the console for details.') 
      const serviceError = lt.Document.ServiceError.parseError(jqXHR, statusText, errorThrown); 
      console.error(serviceError); 
   } 
 
   private init = () => { 
      this.initFactory(); 
      this.testConnection(); 
   } 
 
   private initFactory = () => { 
      lt.RasterSupport.setLicenseUri('https://demo.leadtools.com/licenses/js/LEADTOOLSEVAL.txt', 'EVAL', null); 
 
      // To communicate with the DocumentsService, it must be running! 
      // Change these parameters to match the path to the service. 
      lt.Document.DocumentFactory.serviceHost = 'http://localhost:40000'; 
      lt.Document.DocumentFactory.servicePath = ''; 
      lt.Document.DocumentFactory.serviceApiPath = 'api'; 
   } 
 
   private testConnection = () => { 
      const serviceStatus = document.getElementById('serviceStatus'); 
      serviceStatus.innerHTML = 'Connecting to service: ' + lt.Document.DocumentFactory.serviceUri; 
 
      lt.Document.DocumentFactory.verifyService() 
         .done((serviceData) => { 
            serviceStatus.innerHTML = 'Service connection verified!'; 
            this.createDocumentViewer(); 
         }) 
         .fail((jqXHR, statusText, errorThrown) => { 
            serviceStatus.innerHTML = 'Service connection unavailable.'; 
            ViewerInitializer.showServiceError(jqXHR, statusText, errorThrown); 
         }); 
   } 
 
   private createDocumentViewer = () => { 
      // Initialize the user interface 
      const interactiveSelect = document.getElementById('interactiveSelect'); 
 
      const panZoomOption = document.createElement('option'); 
      panZoomOption.innerHTML = 'Pan / Zoom'; 
      panZoomOption.value = lt.Document.Viewer.DocumentViewerCommands.interactivePanZoom; 
      interactiveSelect.appendChild(panZoomOption); 
 
      const textOption = document.createElement('option'); 
      textOption.value = lt.Document.Viewer.DocumentViewerCommands.interactiveSelectText; 
      textOption.innerHTML = 'Select Text'; 
      interactiveSelect.appendChild(textOption); 
 
      let documentViewer: lt.Document.Viewer.DocumentViewer = null; 
      interactiveSelect.onchange = (e) => documentViewer.commands.run((e.target as HTMLSelectElement).value, null); 
 
      const annotationsSelect = document.getElementById('annotationsSelect'); 
 
      const annSelectOption = document.createElement('option'); 
      annSelectOption.innerHTML = 'Select Annotation'; 
      annSelectOption.value = lt.Annotations.Engine.AnnObject.selectObjectId.toString(); 
      annotationsSelect.appendChild(annSelectOption); 
 
      const annLineOption = document.createElement('option'); 
      annLineOption.innerHTML = 'Line Object'; 
      annLineOption.value = lt.Annotations.Engine.AnnObject.lineObjectId.toString(); 
      annotationsSelect.appendChild(annLineOption); 
 
      const annRectOption = document.createElement('option'); 
      annRectOption.innerHTML = 'Rectangle Object'; 
      annRectOption.value = lt.Annotations.Engine.AnnObject.rectangleObjectId.toString(); 
      annotationsSelect.appendChild(annRectOption); 
      annotationsSelect.onchange = (e) => { 
         const value = +(e.currentTarget as HTMLSelectElement).value; 
         documentViewer.annotations.automationManager.currentObjectId = value; 
      } 
 
      // Init the document viewer, pass along the panels 
      const createOptions = new lt.Document.Viewer.DocumentViewerCreateOptions(); 
      // We are not going to use elements mode in this example 
      createOptions.viewCreateOptions.useElements = false; 
      createOptions.thumbnailsCreateOptions.useElements = false; 
 
      // The middle panel for the view 
      createOptions.viewContainer = document.getElementById('viewer'); 
      // The left panel for the thumbnails 
      createOptions.thumbnailsContainer = document.getElementById('thumbnails'); 
      // The right panel is for bookmarks 
      createOptions.bookmarksContainer = document.getElementById('bookmarks'); 
      createOptions.useAnnotations = true; 
 
      // Create the document viewer 
      documentViewer = lt.Document.Viewer.DocumentViewerFactory.createDocumentViewer(createOptions); 
 
      // We prefer SVG viewing 
      documentViewer.view.preferredItemType = lt.Document.Viewer.DocumentViewerItemType.svg; 
 
      // Create html5 rendering engine 
      documentViewer.annotations.automationManager.renderingEngine = new lt.Annotations.Rendering.AnnHtml5RenderingEngine(); 
      // Initialize documentViewer annotations 
      documentViewer.annotations.initialize(); 
 
      documentViewer.annotations.automationManager.currentObjectIdChanged.add(function (sender, e) { 
         // When done drawing, the manager will return to the select object; so we need force the annotationsSelect element to return to the select object option 
         (annotationsSelect as HTMLSelectElement).value = sender.currentObjectId; 
      }); 
 
      this.loadDefaultDoc(documentViewer, interactiveSelect as HTMLSelectElement) 
   } 
 
   private loadDefaultDoc = (viewer: lt.Document.Viewer.DocumentViewer, interactiveSelect: HTMLSelectElement) => { 
      // Load a PDF document 
      const url = 'https://demo.leadtools.com/images/pdf/leadtools.pdf'; 
      lt.Document.DocumentFactory.loadFromUri(url, null) 
         .done((doc: lt.Document.LEADDocument) => { 
            const ready = () => { 
               viewer.setDocument(doc); 
               const panZoom = lt.Document.Viewer.DocumentViewerCommands.interactivePanZoom; 
               interactiveSelect.value = panZoom; 
               viewer.commands.run(panZoom, null); 
               if(this.callback) 
                  this.callback(viewer); 
            } 
 
            if (doc.isStructureSupported && !doc.structure.isParsed) 
               doc.structure.parse() 
                  .done(ready) 
                  .fail(ViewerInitializer.showServiceError); 
            else 
               ready(); 
         }) 
         .fail(ViewerInitializer.showServiceError); 
   } 
} 
import { ViewerInitializer } from "../utilities/ViewerInitializer"; 
 
export class TextFindJSExample { 
   run = () => { 
      new ViewerInitializer(this.textExample); 
   } 
 
   textExample = (documentViewer) => { 
      const output = document.getElementById('output'); 
      const text = documentViewer.text; 
 
      // Make sure we get the page text if necessary (otherwise, results may be empty!) 
      text.autoGetText = true; 
 
      // We will find all matches of "LEAD", ignoring the case 
      const options = new lt.Document.Viewer.DocumentViewerFindText(); 
 
      // The text 
      options.text = "LEAD"; 
      // Ignore case 
      options.matchCase = false; 
      // Any word that contains the phrase 
      options.wholeWordsOnly = false; 
 
      // Find all results in the bounds, not just the first 
      options.findAll = true; 
 
      // Highlight the results in the View 
      options.renderResults = true; 
      // Optionally, change the highlight color 
      lt.Document.Viewer.DocumentViewerText.foundTextFill = "rgba(255, 255, 0, .4)"; 
 
      // Set direction - this value could be decided from a set of "next" and "previous" buttons 
      const isFindingNext = true; 
      // Set the bounds 
      // We set the bounds as the whole document, but below we can specify to start wherever text is selected 
      // or at the current page 
      const topOfFirstPage = lt.Document.Viewer.DocumentViewerTextPosition.createBeginOfPage(1); 
      const bottomOfLastPage = lt.Document.Viewer.DocumentViewerTextPosition.createEndOfPage(documentViewer.pageCount); 
      if (isFindingNext) { 
         // Make the beginning bound "higher up" the page so we search "down" the page. 
         options.beginPosition = topOfFirstPage; 
         options.endPosition = bottomOfLastPage; 
      } 
      else { 
         // Make the beginning bound "lower down" the page so we search "up" the page. 
         options.beginPosition = bottomOfLastPage; 
         options.endPosition = topOfFirstPage; 
      } 
 
      // Select the first result in the View (automatically scrolls View also) 
      options.selectFirstResult = true; 
 
      if (text.hasAnySelectedText) { 
         // Setting this value to AfterSelection allows us to search forward from the selection, so multiple 
         // uses of this same options object will cycle us through all the matches! 
         // (If no selected text actually exists, search will default to beginPosition.) 
         options.start = lt.Document.Viewer.DocumentViewerFindTextStart.afterSelection; 
      } 
      else { 
         // We could start at the begin position, but it makes more UI sense to start from the user's current page. 
         // Search will loop back around to the begin position - this just changes the starting point and order of results. 
         options.start = lt.Document.Viewer.DocumentViewerFindTextStart.manualPosition; 
         if (isFindingNext) 
            options.manualStartPosition = lt.Document.Viewer.DocumentViewerTextPosition.createBeginOfPage(documentViewer.currentPageNumber); 
         else 
            options.manualStartPosition = lt.Document.Viewer.DocumentViewerTextPosition.createEndOfPage(documentViewer.currentPageNumber); 
      } 
 
      // If we were just looking for the first match, we could use "loop" to loop around 
      // if we found nothing between the start position and the end bound. 
      //options.loop = true; 
 
      // You will likely want to clear the previous highlighted results 
      // on the screen so only our new results will show. 
      text.clearRenderedFoundText(); 
 
      output.innerHTML = "Searching, please wait..."; 
 
      // Search, asynchronously 
      text.find(options, function (results) { 
         const resultsCount = !!results ? results.length : 0; 
 
         let resultText; 
         if (resultsCount > 0) 
            resultText = "Found " + resultsCount + " results for '" + options.text + "'."; 
         else 
            resultText = "No matches found."; 
 
         alert(resultText); 
         output.innerHTML = resultText; 
      }); 
   } 
} 
export class ViewerInitializer { 
   constructor(callback) { 
      this.callback = callback; 
      this.init(); 
   } 
 
   static showServiceError = (jqXHR, statusText, errorThrown) => { 
      alert("Error returned from service. See the console for details.") 
      const serviceError = lt.Document.ServiceError.parseError(jqXHR, statusText, errorThrown); 
      console.error(serviceError); 
   } 
 
   init = () => { 
      this.initFactory(); 
      this.testConnection(); 
   } 
 
   initFactory = () => { 
      lt.RasterSupport.setLicenseUri("https://demo.leadtools.com/licenses/js/LEADTOOLSEVAL.txt", "EVAL", null); 
 
      // To communicate with the DocumentsService, it must be running! 
      // Change these parameters to match the path to the service. 
      lt.Document.DocumentFactory.serviceHost = "http://localhost:40000"; 
      lt.Document.DocumentFactory.servicePath = ""; 
      lt.Document.DocumentFactory.serviceApiPath = "api"; 
   } 
 
   testConnection = () => { 
      const serviceStatus = document.getElementById("serviceStatus"); 
      serviceStatus.innerHTML = "Connecting to service: " + lt.Document.DocumentFactory.serviceUri; 
 
      lt.Document.DocumentFactory.verifyService() 
         .done((serviceData) => { 
            serviceStatus.innerHTML = "Service connection verified!"; 
            this.createDocumentViewer(); 
         }) 
         .fail((jqXHR, statusText, errorThrown) => { 
            serviceStatus.innerHTML = "Service connection unavailable."; 
            ViewerInitializer.showServiceError(jqXHR, statusText, errorThrown); 
         }); 
   } 
 
   createDocumentViewer = () => { 
      // Initialize the user interface 
      const interactiveSelect = document.getElementById("interactiveSelect"); 
 
      const panZoomOption = document.createElement("option"); 
      panZoomOption.innerHTML = "Pan / Zoom"; 
      panZoomOption.value = lt.Document.Viewer.DocumentViewerCommands.interactivePanZoom; 
      interactiveSelect.appendChild(panZoomOption); 
 
      const textOption = document.createElement("option"); 
      textOption.value = lt.Document.Viewer.DocumentViewerCommands.interactiveSelectText; 
      textOption.innerHTML = "Select Text"; 
      interactiveSelect.appendChild(textOption); 
 
      let documentViewer = null; 
      interactiveSelect.onchange = (e) => documentViewer.commands.run(e.target.value, null); 
 
      const annotationsSelect = document.getElementById("annotationsSelect"); 
 
      const annSelectOption = document.createElement("option"); 
      annSelectOption.innerHTML = "Select Annotation"; 
      annSelectOption.value = lt.Annotations.Engine.AnnObject.selectObjectId.toString(); 
      annotationsSelect.appendChild(annSelectOption); 
 
      const annLineOption = document.createElement("option"); 
      annLineOption.innerHTML = "Line Object"; 
      annLineOption.value = lt.Annotations.Engine.AnnObject.lineObjectId.toString(); 
      annotationsSelect.appendChild(annLineOption); 
 
      const annRectOption = document.createElement("option"); 
      annRectOption.innerHTML = "Rectangle Object"; 
      annRectOption.value = lt.Annotations.Engine.AnnObject.rectangleObjectId.toString(); 
      annotationsSelect.appendChild(annRectOption); 
      annotationsSelect.onchange = (e) => { 
         const value = +e.currentTarget.value; 
         documentViewer.annotations.automationManager.currentObjectId = value; 
      } 
 
      // Init the document viewer, pass along the panels 
      const createOptions = new lt.Document.Viewer.DocumentViewerCreateOptions(); 
      // We are not going to use elements mode in this example 
      createOptions.viewCreateOptions.useElements = false; 
      createOptions.thumbnailsCreateOptions.useElements = false; 
 
      // The middle panel for the view 
      createOptions.viewContainer = document.getElementById("viewer"); 
      // The left panel for the thumbnails 
      createOptions.thumbnailsContainer = document.getElementById("thumbnails"); 
      // The right panel is for bookmarks 
      createOptions.bookmarksContainer = document.getElementById("bookmarks"); 
      createOptions.useAnnotations = true; 
 
      // Create the document viewer 
      documentViewer = lt.Document.Viewer.DocumentViewerFactory.createDocumentViewer(createOptions); 
 
      // We prefer SVG viewing 
      documentViewer.view.preferredItemType = lt.Document.Viewer.DocumentViewerItemType.svg; 
 
      // Create html5 rendering engine 
      documentViewer.annotations.automationManager.renderingEngine = new lt.Annotations.Rendering.AnnHtml5RenderingEngine(); 
      // Initialize documentViewer annotations 
      documentViewer.annotations.initialize(); 
 
      documentViewer.annotations.automationManager.currentObjectIdChanged.add(function (sender, e) { 
         // When done drawing, the manager will return to the select object; so we need force the annotationsSelect element to return to the select object option 
         annotationsSelect.value = sender.currentObjectId; 
      }); 
 
      this.loadDefaultDoc(documentViewer, interactiveSelect) 
   } 
 
   loadDefaultDoc = (viewer, interactiveSelect) => { 
      // Load a PDF document 
      const url = "https://demo.leadtools.com/images/pdf/leadtools.pdf"; 
      lt.Document.DocumentFactory.loadFromUri(url, null) 
         .done((doc) => { 
            const ready = () => { 
               viewer.setDocument(doc); 
               const panZoom = lt.Document.Viewer.DocumentViewerCommands.interactivePanZoom; 
               interactiveSelect.value = panZoom; 
               viewer.commands.run(panZoom, null); 
               if(this.callback) 
                  this.callback(viewer); 
            } 
 
            if (doc.isStructureSupported && !doc.structure.isParsed) 
               doc.structure.parse() 
                  .done(ready) 
                  .fail(ViewerInitializer.showServiceError); 
            else 
               ready(); 
         }) 
         .fail(ViewerInitializer.showServiceError); 
   } 
} 
<!doctype html> 
<html lang="en"> 
<title>DocViewer Example | DocumentViewer</title> 
 
<head> 
   <script src="https://code.jquery.com/jquery-2.2.4.min.js" 
      integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> 
 
   <script src="../LT/Leadtools.js"></script> 
   <script src="../LT/Leadtools.Controls.js"></script> 
   <script src="../LT/Leadtools.Annotations.Engine.js"></script> 
   <script src="../LT/Leadtools.Annotations.Designers.js"></script> 
   <script src="../LT/Leadtools.Annotations.Rendering.Javascript.js"></script> 
   <script src="../LT/Leadtools.Annotations.Automation.js"></script> 
   <script src="../LT/Leadtools.ImageProcessing.Main.js"></script> 
   <script src="../LT/Leadtools.ImageProcessing.Color.js"></script> 
   <script src="../LT/Leadtools.ImageProcessing.Core.js"></script> 
   <script src="../LT/Leadtools.ImageProcessing.Effects.js"></script> 
   <script src="../LT/Leadtools.Document.js"></script> 
   <script src="../LT/Leadtools.Document.Viewer.js"></script> 
   <link rel="stylesheet" type="text/css" href="../css/examples.css"> 
 
   <!-- All demo files are bundled and appended to the window --> 
   <script src="../bundle.js" type="text/javascript"></script> 
</head> 
 
 
<body> 
   <div class="container"> 
      <div class="toolbar"> 
         <div class="vcenter push-right"> 
            <button type="button" id="exampleButton">Run Example</button> 
         </div> 
         <div class="vcenter push-right"> 
            <label for="interactiveSelect">Interactive mode:</label> 
            <select id="interactiveSelect"></select> 
         </div> 
         <div class="vcenter push-right"> 
            <label for="annotationsSelect">Annotations objects:</label> 
            <select id="annotationsSelect"></select> 
         </div> 
         <div id="output" class="vcenter push-right"></div> 
         <div id="serviceStatus" class="vcenter push-right"></div> 
      </div> 
      <div class="docContainer"> 
         <div class="sidepanel" id="thumbnails"></div> 
         <div class="centerpanel" id="viewer"></div> 
         <div class="sidepanel" id="bookmarks"></div> 
      </div> 
   </div> 
</body> 
<script> 
   window.onload = () => { 
      const button = document.getElementById('exampleButton'); 
      button.onclick = () => { 
         const example = new window.examples.TextFindExample(); 
         example.run(); 
      } 
   }; 
</script> 
 
</html> 
 /* 
   Remove default body styling. 
   Set the body to flex as a column; 
*/ 
body { 
   margin: 0; 
   display: flex; 
   flex-direction: column; 
} 
 
.container { 
   margin: 10px; 
   width: calc(100% - 20px); 
   height: calc(100vh - 20px); 
} 
 
.toolbar { 
   height: 5%; 
   width: 100%; 
   border-bottom: 2px solid #333; 
   flex-direction: row; 
   display: flex; 
} 
#bookmarks{ 
   overflow: hidden; 
} 
 
.vcenter { 
   margin-top: auto; 
   margin-bottom: auto; 
} 
 
.hcenter{ 
   margin-left: auto; 
   margin-right: auto; 
} 
 
.push-right{ 
   margin-left: 10px; 
} 
 
.docContainer{ 
   height: 95%; 
   width: 100%; 
   display: flex; 
   flex-direction: row; 
} 
 
.sidepanel{ 
   width: 15%; 
   height: 100%; 
} 
 
.centerpanel{ 
   width:100%; 
   height:100%; 
} 
 
 /* Styles for Elements Mode. */ 
 .lt-item, .lt-image-border { 
   /* Box Shadow (view, item, image border) */ 
   box-shadow: #333 2px 2px 5px 1px; 
 } 
 .lt-view,.lt-thumb-item { 
   /* View */ 
   margin: 5px; 
   padding: 5px; 
 } 
 .lt-item { 
   /* Item */ 
   border: 2px solid #6ecaab; 
   background-color: #b2decf; 
   padding: 10px; 
 } 
 .lt-image-border { 
   /* Image Border */ 
   border: 3px solid #444; 
   background-color: white; 
 } 
 .lt-thumb-item { 
   /* Thumbnail Item */ 
   border: 2px solid #6ecaab; 
   background-color: #b2decf; 
 } 
 .lt-thumb-item.lt-thumb-item-selected { 
   /* Selected Thumbnail Item */ 
   border: 2px solid #59b2ba; 
   background-color: #8ce1e1; 
 } 
 .lt-thumb-item-hovered { 
   /* Hovered Thumbnail Item */ 
   border: 2px solid #52b996; 
   background-color: #87c7b1; 
 } 
 .small-modal { 
   max-width: 200px; 
   width: 200px; 
 } 
Requirements

Target Platforms

Help Version 22.0.2023.4.18
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.

Leadtools.Document.Viewer Assembly
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.