@progress/telerik-jquery-report-viewer
Version:
Progress® Telerik® Report Viewer for jQuery
585 lines (580 loc) • 21 kB
JavaScript
'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;