Search
Native text search in the Viewer composition
The Doconut Viewer provides normal Search using text extracted by the format viewer or a
text-based PDF redirect. It requires the Search license capability.
Enable the search UI
Search is a Viewer module, not a standalone toolbar. The complete page must include the
Viewer resources, Viewer toolbar, Viewer mount, and initialized objViewer; the Search
Ribbon is then mounted and attached to that same instance.
Search and annotation are built-in licensed features, not AddPlugin<T>() packages. Request the search resources from the injected Viewer; their tags are emitted only when the license grants Search.
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
IncludeViewerCss = true,
IncludeSearchCss = true
}))
@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
IncludeJQuery = true,
IncludeViewerScripts = true,
IncludeSearchScripts = true,
IncludeSearchBar = true
}))The embedded ribbon calls the same JavaScript methods available to a custom UI.
Keep the complete Viewer composition visible in the markup, initialize docViewer first,
and then attach the licensed Ribbon:
<nav id="toolbar" aria-label="Document viewer controls">
<!-- Viewer controls, including the button that opens Search -->
</nav>
<div id="searchBarMount"></div>
<div id="divDocViewer"><div id="div_ctlDoc"></div></div>
<script>
let searchBar = null;
let currentToken = '';
const objViewer = $('#div_ctlDoc').docViewer({
BasePath: '/doconut',
ResPath: '/doconut-res/images'
});
@if (Viewer.IsSearchEnabled)
{
<text>
searchBar = $('#searchBarMount').doconutSearchBar({
docId: 'ctlDoc',
getRequestParams: () => ({ token: currentToken }),
onStatus: (message) => console.log(message),
onToast: (message, type) => console.log(type, message),
onLayout: () => requestAnimationFrame(() => objViewer.Refit())
});
searchBar.attach(objViewer);
</text>
}
</script>The component injects Find, Options, and Results groups and handles searching, clearing, match counts, and previous/next match navigation. A host-owned Viewer toolbar only needs to toggle it:
searchBar.isOpen() ? searchBar.close() : searchBar.open();Its public API is intentionally small:
| Method | Purpose |
|---|---|
attach(objViewer) | Connect the Ribbon to the initialized viewer; required once |
open() / close() | Show or hide the Ribbon; closing also clears highlights |
reset() | Clear the current term, result count, and highlights |
isOpen() | Report whether the Ribbon is visible |
setStatus(message) | Forward a status message through the configured callback |
The optional onToggle(isOpen) callback lets the host synchronize its Search button, and
onLayout lets it resize/refit the viewer when the Ribbon changes height. For the combined
Viewer, Search, and Annotation startup sequence, see
Quick Start.
Search from JavaScript
objViewer.Search(keyword, false, function (resultCount) {
console.log('Matches:', resultCount);
});The second argument is whole-word/exact matching. After the callback:
| Method | Result |
|---|---|
SearchMatchCount() | Total individual matches in the document. |
SearchSummary(false) | [pageNumber, matchCount] entries without repainting. |
SearchSummary(true) | Same summary and paints page/thumbnail highlights. |
GotoSearchMatch(index) | Navigates to a zero-based match index. |
The middleware route uses search=<term> and exact=true|false and returns XML. Use the widget API rather than parsing that internal response yourself.
Check search capability
The initialization response reports:
X-Doconut-Can-Search: 1After initialization, objViewer.CanSearch() exposes the same format/session verdict. It returns false when the server sends 0; before the response, or with an older server that omits the header, it defaults to true.
Three independent gates must not be confused:
| Gate | Question |
|---|---|
CanSearch() / response header | Does the resolved viewer have a native index/search path? |
AllowSearch | Did this format config request text extraction where the switch exists? |
LicenseCapability.Search | Is the application authorized to execute search and receive the UI bundles? |
A format can be technically searchable while the current license denies the operation.
Enable extraction per format
var token = await viewer.OpenDocumentAsync(path, new PdfConfig
{
AllowSearch = true,
AllowCopy = true // optional: lets the user drag a region and copy its text
});AllowSearch and AllowCopy exist on PdfConfig, WordConfig, ExcelConfig, and PptConfig. The Office properties delegate to their nested PdfConfig. Both default to false.
Normal native-search adapters exist for PDF, Word, Excel, PowerPoint, TXT, Visio, email, EPUB, and MHT. XPS uses its PDF path by default. HTML and Microsoft Project benefit from a text-based PDF redirect:
// DefaultRender = false → converted to a text-based PDF → searchable
var token = await viewer.OpenDocumentAsync(path, new HtmlConfig { DefaultRender = false });For native renderers, CanSearch() describes the viewer capability; it does not guarantee that a particular document contains usable text. A PDF whose pages are only scanned images can still produce zero native results.
Normal Search behavior
The server tries search sources in this order:
- Native
ISearchableViewerresults. - A prebuilt
.srhsearch index. - An error/empty result when no search source exists.
CanSearch() can be true for a searchable viewer even when a particular document has no
text layer and therefore returns no matches.
Licensing and UI behavior
An active Temporary/Demo license grants Search during its active period. A missing license and legacy TRIAL file grant no Search capability. Without Search:
ReferenceCssandReferenceScriptsomit the search bundles.- The middleware denies search instead of returning licensed results.
Drive custom UI visibility from IDoconutLicenseService.IsCapabilityGranted(LicenseCapability.Search) and use CanSearch() for the separate format/session verdict.
Troubleshooting
| Symptom | Check |
|---|---|
| Search bar is missing | Search capability and IncludeSearchCss/IncludeSearchScripts/IncludeSearchBar |
CanSearch() is false | Format viewer, selected DefaultRender path, and initialization response header |
| Search returns zero for a scanned PDF | The document has no text layer; use a text-bearing source or a PDF projection that preserves text |
| Search works but highlights are offset | Rendering path, resolution, document transforms, and extracted word boxes |
Was this page helpful?