UNPKG

@progress/telerik-jquery-report-viewer

Version:

Progress® Telerik® Report Viewer for jQuery

585 lines (580 loc) 21 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var utils = require('./utils.js'); var stringResources = require('./stringResources.js'); var binder = require('./binder.js'); var enums = require('./enums.js'); var command = require('./command.js'); var defaultOptions = {}; function replaceStringResources($search) { if (!$search) { return; } var $searchCaption = $search.find(".trv-search-dialog-caption-label"); var $searchOptions = $search.find(".trv-search-dialog-search-options"); var $searchStopButton = $search.find("a[data-command='telerik_ReportViewer_searchDialog_StopSearch']"); var $searchMatchCaseButton = $search.find("a[data-command='telerik_ReportViewer_searchDialog_MatchCase']"); var $searchMatchWholeWordButton = $search.find("a[data-command='telerik_ReportViewer_searchDialog_MatchWholeWord']"); var $searchUseRegexButton = $search.find("a[data-command='telerik_ReportViewer_searchDialog_UseRegex']"); var $searchNavigateUpButton = $search.find("a[data-command='telerik_ReportViewer_searchDialog_NavigateUp']"); var $searchNavigateDownButton = $search.find("a[data-command='telerik_ReportViewer_searchDialog_NavigateDown']"); replaceAttribute($search, "aria-label"); replaceAttribute($searchOptions, "aria-label"); replaceText($searchCaption); replaceTitleAndAriaLabel($searchStopButton); replaceTitleAndAriaLabel($searchMatchCaseButton); replaceTitleAndAriaLabel($searchMatchWholeWordButton); replaceTitleAndAriaLabel($searchUseRegexButton); replaceTitleAndAriaLabel($searchNavigateUpButton); replaceTitleAndAriaLabel($searchNavigateDownButton); } function replaceTitleAndAriaLabel($a) { replaceAttribute($a, "title"); replaceAttribute($a, "aria-label"); } function replaceText($el) { if ($el) { $el.text(stringResources.stringResources[$el.text()]); } } function replaceAttribute($el, attribute) { if ($el) { $el.attr(attribute, stringResources.stringResources[$el.attr(attribute)]); } } class Search { constructor(element, options, viewerOptions) { this.options = $.extend({}, defaultOptions, options); this.viewerOptions = viewerOptions; this.element = element; this.controller = this.options.controller; this.initialized = false; this.dialogVisible = false; this.$element; this.$inputBox; this.$searchOptionsPlaceholder; this.searchOptionsMenu; this.$stopSearchPlaceholder; this.stopSearchMenu; this.$navigationPlaceholder; this.navigationMenu; this.$resultsLabel; this.$resultsPlaceholder; this.kendoComboBox; this.kendoSearchDialog; this.stopSearchCommand; this.optionsCommandSet; this.navigationCommandSet; this.searchResults; this.mruList = []; this.inputComboRebinding; this.searchMetadataRequested; this.searchMetadataLoaded; this.pendingHighlightItem; this.windowLocation; this.reportViewerWrapper = $("[data-selector='" + this.viewerOptions.viewerSelector + "']").find(".trv-report-viewer"); this.lastSearch = ""; this.highlightManager = { // the results that are found, but not selected (highlighted) shadedClassName: "trv-search-dialog-shaded-result", // the result that is currently selected (highlighted) highlightedClassName: "trv-search-dialog-highlighted-result", current: null, elements: [] }; if (!this.controller) { throw "No controller (telerikReporting.ReportViewerController) has been specified."; } this.controller.pageReady(this.onPageReady.bind(this)).scrollPageReady(this.onPageReady.bind(this)).beginLoadReport(this.closeAndClear.bind(this)).viewModeChanged(this.closeAndClear.bind(this)); this.controller.setSendEmailDialogVisible((event, args) => { if (args.visible && this.dialogVisible) { this.toggle(!this.dialogVisible); } }).getSearchDialogState((event, args) => { args.visible = this.dialogVisible; }).setSearchDialogVisible((event, args) => { this.toggleSearchDialog(args.visible); }); $(window).on("resize", () => { if (this.kendoSearchDialog && this.kendoSearchDialog.options.visible) { this.storeDialogPosition(); this.adjustDialogPosition(); } }); } closeAndClear() { if (this.searchMetadataRequested) { return; } this.toggle(false); this.searchMetadataLoaded = false; } toggleSearchDialog(show) { this.dialogVisible = show; if (show) { var searchMetadataOnDemand = this.viewerOptions.searchMetadataOnDemand; if (searchMetadataOnDemand && !this.searchMetadataLoaded) { this.searchMetadataRequested = true; this.controller.reportLoadComplete((event, args) => { if (this.searchMetadataRequested) { this.toggle(true); this.searchMetadataRequested = false; } }); this.controller.refreshReport(true); return; } } this.toggle(show); } toggle(show) { this.dialogVisible = show; if (show) { this.searchMetadataLoaded = true; this.ensureInitialized(); this.kendoSearchDialog.open(); this.kendoComboBox.value(""); this.updateResultsUI(null); this.toggleErrorLabel(false, null); } else { this.clearColoredItems(); if (this.kendoSearchDialog && this.kendoSearchDialog.options.visible) { this.kendoSearchDialog.close(); } } } ensureInitialized() { if (!this.initialized) { this.$element = $(this.element); this.$inputBox = this.$element.find(".trv-search-dialog-input-box"); this.$resultsLabel = this.$element.find(".trv-search-dialog-results-label"); this.$resultsPlaceholder = this.$element.find(".trv-search-dialog-results-area"); this.initResultsArea(); replaceStringResources(this.$element); try { this.$searchOptionsPlaceholder = this.$element.find(".trv-search-dialog-search-options").kendoMenu(); this.$stopSearchPlaceholder = this.$element.find(".trv-search-dialog-stopsearch-placeholder").kendoMenu(); this.$navigationPlaceholder = this.$element.find(".trv-search-dialog-navigational-buttons").kendoMenu(); } catch (error) { console.error("Instantiation of Kendo Menu for Search Dialog threw an exception", error); throw error; } this.searchOptionsMenu = this.$searchOptionsPlaceholder.data("kendoMenu"); this.stopSearchMenu = this.$stopSearchPlaceholder.data("kendoMenu"); this.navigationMenu = this.$navigationPlaceholder.data("kendoMenu"); this.searchOptionsMenu.element.on("keydown", this.onKeyDown); this.stopSearchMenu.element.on("keydown", this.onKeyDown); this.navigationMenu.element.on("keydown", this.onKeyDown); this.overrideDefaultMenuStyling(".trv-search-dialog-search-options"); try { this.kendoComboBox = this.$inputBox.kendoComboBox({ dataTextField: "value", dataValueField: "value", dataSource: this.mruList, contentElement: "", change: this.kendoComboBoxSelect.bind(this), ignoreCase: false, // the actual search-when-typing performs on this event. filtering: this.onInputFiltering.bind(this), filter: "startswith", delay: 1e3, open: (event) => { if (this.inputComboRebinding) { event.preventDefault(); } }, select: this.processComboBoxEvent.bind(this) }).data("kendoComboBox"); } catch (error) { console.error("Instantiation of Kendo ComboBox as search input threw an exception", error); throw error; } try { this.kendoSearchDialog = this.reportViewerWrapper.find(".trv-search-window").kendoWindow({ title: stringResources.stringResources.searchDialogTitle, height: 390, width: 310, minWidth: 310, minHeight: 390, maxHeight: 700, scrollable: false, close: () => { this.storeDialogPosition(); this.lastSearch = ""; }, open: () => { this.adjustDialogPosition(); }, deactivate: () => { this.controller.setSearchDialogVisible({ visible: false }); }, activate: () => { this.kendoComboBox.input.focus(); } }).data("kendoWindow"); } catch (error) { console.error("Instantiation of Kendo Window for Search dialog threw an exception", error); throw error; } this.kendoSearchDialog.wrapper.addClass("trv-search"); this.initCommands(); this.initialized = true; } } overrideDefaultMenuStyling(kendoMenuSelector) { var menuItems = $(kendoMenuSelector).find(".k-menu-item"); for (var i = 0; i < menuItems.length; i++) { $(menuItems[i]).removeClass("k-item"); } } onKeyDown(event) { var item = $(event.target).find(".k-focus"); if (event.keyCode === 13 && item && item.length > 0) { var anchor = item.children("a"); if (anchor.length > 0) { anchor.click(); } } } storeDialogPosition() { var kendoWindow = this.kendoSearchDialog.element.parent(".k-window"); this.windowLocation = kendoWindow.offset(); } adjustDialogPosition() { var windowWidth = $(window).innerWidth(); var windowHeight = $(window).innerHeight(); var kendoWindow = this.kendoSearchDialog.wrapper; var width = kendoWindow.outerWidth(true); var height = kendoWindow.outerHeight(true); var padding = 10; if (!this.windowLocation) { var reportViewerCoords = this.reportViewerWrapper[0].getBoundingClientRect(); kendoWindow.css({ top: reportViewerCoords.top + padding, left: reportViewerCoords.right - width - padding }); this.kendoSearchDialog.setOptions({ position: { top: reportViewerCoords.top + padding, left: reportViewerCoords.right - width - padding } }); } else { var left = this.windowLocation.left; var top = this.windowLocation.top; var right = left + width; var bottom = top + height; if (right > windowWidth - padding) { left = Math.max(padding, windowWidth - width - padding); kendoWindow.css({ left }); this.kendoSearchDialog.setOptions({ position: { left } }); } if (bottom > windowHeight - padding) { top = Math.max(padding, windowHeight - height - padding); kendoWindow.css({ top }); this.kendoSearchDialog.setOptions({ position: { top } }); } } } processComboBoxEvent(event) { if (!(window.event || window.event.type)) { return; } var evt = window.event; if (evt.type === "keydown") { event.preventDefault(); if (evt.keyCode === 40) { this.moveListSelection(1); } if (evt.keyCode === 38) { this.moveListSelection(-1); } } } initCommands() { this.optionsCommandSet = { "searchDialog_MatchCase": new command.Command(), "searchDialog_MatchWholeWord": new command.Command(), "searchDialog_UseRegex": new command.Command() }; Object.entries(this.optionsCommandSet).forEach(([commandName, command]) => { command.exec = () => { this.toggleCommand(command); }; }); binder.Binder.attachCommands(this.$searchOptionsPlaceholder, this.optionsCommandSet, this.viewerOptions); this.stopSearchCommand = new command.Command(() => { this.stopSearch(); }); binder.Binder.attachCommands(this.$stopSearchPlaceholder, { "searchDialog_StopSearch": this.stopSearchCommand }, this.viewerOptions); this.navigationCommandSet = { "searchDialog_NavigateUp": new command.Command(() => { this.moveListSelection(-1); }), "searchDialog_NavigateDown": new command.Command(() => { this.moveListSelection(1); }) }; binder.Binder.attachCommands(this.$navigationPlaceholder, this.navigationCommandSet, this.viewerOptions); } initResultsArea() { try { this.$resultsPlaceholder.kendoListView({ selectable: true, navigatable: true, dataSource: {}, contentElement: "", template: "<div class='trv-search-dialog-results-row'><span>#: description #</span> <span class='trv-search-dialog-results-pageSpan'>" + stringResources.stringResources.searchDialogPageText + " #:page#</span></div>", change: (event) => { var listView = event.sender; var index = listView.select().index(); var view = listView.dataSource.view(); var dataItem = view[index]; this.onSelectedItem(dataItem); this.updateUI(index, view.length); } }); } catch (error) { console.error("Instantiation of Kendo ListView as search result area threw an exception", error); throw error; } } stopSearch() { this.setStopButtonEnabledState(false); } toggleCommand(cmd) { cmd.checked(!cmd.checked()); this.searchForCurrentToken(); } setStopButtonEnabledState(enabledState) { this.stopSearchCommand.enabled(enabledState); } onPageReady(args, page) { if (this.dialogVisible) { this.colorPageElements(this.searchResults); } } onInputFiltering(event) { event.preventDefault(); if (event.filter && event.filter.value !== this.lastSearch) { this.lastSearch = event.filter.value; this.searchForToken(this.lastSearch); } } kendoComboBoxSelect(event) { var newValue = event.sender.value(); if (newValue && this.lastSearch !== newValue) { this.lastSearch = newValue; this.searchForToken(this.lastSearch); } } searchForCurrentToken() { if (this.kendoComboBox) { this.searchForToken(this.kendoComboBox.value()); } } searchForToken(token) { this.onSearchStarted(); this.addToMRU(token); this.controller.getSearchResults( { searchToken: token, matchCase: this.optionsCommandSet.searchDialog_MatchCase.checked(), matchWholeWord: this.optionsCommandSet.searchDialog_MatchWholeWord.checked(), useRegex: this.optionsCommandSet.searchDialog_UseRegex.checked() } ).then((results) => { this.updateResultsUI(results, null); }).catch((errorMessage) => { if (errorMessage) { this.updateResultsUI(null, errorMessage); } }); } onSearchStarted() { this.$resultsLabel.text(stringResources.stringResources.searchDialogSearchInProgress); this.clearColoredItems(); this.searchResults = null; this.setStopButtonEnabledState(true); this.toggleErrorLabel(false, null); } updateResultsUI(results, error) { this.setStopButtonEnabledState(false); if (error) { this.toggleErrorLabel(true, error); } this.displayResultsList(results); this.searchResults = results; if (results && results.length > 0) { this.colorPageElements(results); this.selectFirstElement(); } else { this.updateUI(-1, 0); } } addToMRU(token) { if (!token || token === "") { return; } var exists = this.mruList.filter((mru) => { return mru.value === token; }); if (exists && exists.length > 0) { return; } this.mruList.unshift({ value: token }); if (this.mruList.length > 10) { this.mruList.pop(); } this.inputComboRebinding = true; this.kendoComboBox.dataSource.data(this.mruList); this.kendoComboBox.select((item) => { return item.value === token; }); this.inputComboRebinding = false; } displayResultsList(results) { var $listView = this.$resultsPlaceholder.data("kendoListView"); if (!results) { results = []; } $listView.dataSource.data(results); } colorPageElements(results) { if (!results || results.length === 0) { return; } var $parent = this.$element.parent(); var $pageContainer = $parent.find(".trv-page-container"); var elements = $pageContainer.find("[data-search-id]"); Array.from(results).forEach((result) => { var $searchElement = elements.filter("[data-search-id=" + result.id + "]"); if ($searchElement) { $searchElement.addClass(this.highlightManager.shadedClassName); this.highlightManager.elements.push($searchElement); } }); this.highlightItem(this.pendingHighlightItem); this.pendingHighlightItem = null; } highlightItem(item) { if (item) { var currentItemId = item.id; var newHighlighted = $(this.highlightManager.elements.filter((i) => { return i.attr("data-search-id") === currentItemId; })).first(); if (newHighlighted) { this.highlightManager.current = newHighlighted[0]; if (this.highlightManager.current) { var current = $("[data-search-id='" + currentItemId + "']"); current.removeClass(this.highlightManager.shadedClassName); current.addClass(this.highlightManager.highlightedClassName); } } } } selectFirstElement() { var $listView = this.$resultsPlaceholder.data("kendoListView"); var first = $listView.element.children().first(); $listView.select(first); $listView.trigger("change"); } onSelectedItem(item) { if (!item) { return; } if (this.highlightManager.current) { this.highlightManager.current.removeClass(this.highlightManager.highlightedClassName); this.highlightManager.current.addClass(this.highlightManager.shadedClassName); } if (item.page === this.controller.getCurrentPageNumber()) { this.highlightItem(item); } else { if (this.controller.getPageMode() !== enums.PageModes.CONTINUOUS_SCROLL) { this.clearColoredItems(); } else { this.highlightItem(item); } } this.pendingHighlightItem = item; this.controller.navigateToPage(item.page, { type: "search", id: item.id }); } updateUI(index, count) { var str = count === 0 ? stringResources.stringResources.searchDialogNoResultsLabel : utils.stringFormat(stringResources.stringResources.searchDialogResultsFormatLabel, [index + 1, count]); this.$resultsLabel.text(str); var allowMoveUp = index > 0; var allowMoveDown = index < count - 1; this.navigationCommandSet.searchDialog_NavigateUp.enabled(allowMoveUp); this.navigationCommandSet.searchDialog_NavigateDown.enabled(allowMoveDown); } clearColoredItems() { if (this.highlightManager.elements && this.highlightManager.elements.length > 0) { Array.from(this.highlightManager.elements).forEach(($element) => { $element.removeClass(this.highlightManager.shadedClassName); }); } if (this.highlightManager.current) { this.highlightManager.current.removeClass(this.highlightManager.highlightedClassName); } this.highlightManager.elements = []; this.highlightManager.current = null; } moveListSelection(offset) { var $listView = this.$resultsPlaceholder.data("kendoListView"); var $selected = $listView.select(); if (!$selected) { $selected = $listView.element.children().first(); $listView.select($selected); $listView.trigger("change"); } else { var index = $listView.select().trigger("change").index(); var view = $listView.dataSource.view(); var newIndex = Math.min(view.length - 1, Math.max(0, index + offset)); if (newIndex !== index) { var dataItem = view[newIndex]; var element = $listView.element.find('[data-uid="' + dataItem.uid + '"]'); if (element) { $listView.select(element); $listView.trigger("change"); this.scrollIfNeeded(element[0], $listView.element[0]); } } } } scrollIfNeeded(element, container) { if (element.offsetTop - element.clientHeight < container.scrollTop) { element.scrollIntoView(); } else { var offsetBottom = element.offsetTop + element.offsetHeight; var scrollBottom = container.scrollTop + container.offsetHeight; if (offsetBottom > scrollBottom) { container.scrollTop = offsetBottom - container.offsetHeight; } } } toggleErrorLabel(show, message) { var $errorIcon = this.$searchOptionsPlaceholder.find("i[data-role='telerik_ReportViewer_SearchDialog_Error']"); if (!$errorIcon || $errorIcon.length === 0) { console.log(message); return; } var menuItem = this.$searchOptionsPlaceholder.data("kendoMenu").element.find("li").last(); if (show) { $errorIcon[0].title = message; menuItem.show(); } else { menuItem.hide(); } } } exports.Search = Search;