Skip to main content

ReportDesignerClientSideEventsBuilder.CustomizeOpenDialog(String) Method

Sets the name of the JavaScript function or the entire code that will handle the Web Report Designer‘s CustomizeOpenDialog client-side event.

Namespace: DevExpress.AspNetCore.Reporting.ReportDesigner

Assembly: DevExpress.AspNetCore.Reporting.v23.2.dll

NuGet Package: DevExpress.AspNetCore.Reporting


public ReportDesignerClientSideEventsBuilder CustomizeOpenDialog(
    string callback


Name Type Description
callback String

The name of a JavaScript function or the entire JavaScript function code used to handle the CustomizeOpenDialog event.


Type Description

A ReportDesignerClientSideEventsBuilder that can be used to further configure the Report Designer Client Side Events.


The Open Report dialog appears in the Web Report Designer when opening a report (when the user clicks the Open menu command).

To customize the Open dialog, handle the CustomizeOpenDialog event and call the e.Customize method.


The complete sample project How to Customize the Save As and Open Dialogs in the Web End-User Report Designer is available in the DevExpress Examples repository.

Report files in this example are arranged in folders in the root Reports folder. Folder names correspond to the report’s Category. The customized dialog displays report names and categories.

Custom Open Dialog

The Open dialog is defined in a HTML template.

The dialog model defines the properties used in the dialog template and binds them to Knockout observables. The model specifies the following functions:

  • to set the current report URL
  • to get the current report URL
  • to update the model’s properties when the dialog is displayed. The updateCategories JavaScript function is used.

The updateCategories function calls the client-side DevExpress.Reporting.Designer.ReportStorageWeb.getUrls method to obtain report names and categories. This method uses the ReportStorageWebExtension.GetUrls method of a server-side report storage to get a dictionary that contains report names and categories. The code processes the dictionary and fills the categories data array.

The model defines the dialog buttons and their actions. The Open button’s action calls the method and the Cancel button’s action calls the e.Popup.cancel method.

The dialog HTML template and dialog model are passed to the e.Customize(template, model) method to modify the Report Designer’s Open dialog. This method is available in the CustomizeOpenDialog event handler.

The customizeOpenDialog function is the CustomizeOpenDialog event handler. The function uses the ASPxClientReportDesignerCustomizeOpenDialogEventArgs.Popup property to specify the dialog’s width, height, and title. The function defines variables used in the dialog model and defines the dialog model. Finally, the function calls the e.Customize method to modify the dialog based on the specified model and template.

<script type="text/javascript" id="script">
    function addReport(url, category, categoryArray, categoryName, reportName, value, koCategory) {
        if(category.length === 0) {
                key: categoryName, items: [
                        text: value.Key, displayName: reportName,
                        onClick: function () { url(value.Key); koCategory && koCategory(categoryName); }
        } else {
                text: value.Key, displayName: reportName,
                onClick: function () { url(value.Key); koCategory && koCategory(categoryName); }

    function updateCategories(url, categories, koCategory) {
        DevExpress.Reporting.Designer.ReportStorageWeb.getUrls().done(function(result) {
            var categoryArray = [{ key: "none", items: [] }];
            for(var i = 0; i < result.length; i++) {
                var parts = result[i].Value.split('\\');
                var folder = parts[0];
                var reportName = parts[1];
                if(parts.length === 1) {
                    reportName = parts[0];
                    folder = "none";
                } else if (parts.length > 2) {
                    reportName = parts.pop();
                    folder = parts.join('\\');
                var category = categoryArray.filter(function(item) { return item.key === folder; });
                addReport(url, category, categoryArray, folder, reportName, result[i], koCategory);

    function customizeOpenDialog(s, e) {
        e.Popup.title = "Open";
        var categories = ko.observableArray([]);
        var koUrl = ko.observable("");
        var koInput = ko.observable("");
        updateCategories(koUrl, categories);

        var model = {
            categories: categories,
            reportUrl: koUrl,
            inputValue: koInput,
            setUrl: function(url) {
            getUrl: function() {
                return koUrl();
            onShow: function(tab) {
                updateCategories(koUrl, categories);
            popupButtons: [
                    toolbar: 'bottom', location: 'after', widget: 'dxButton', options: {
                        text: 'Open', onClick: function() {
                    toolbar: 'bottom', location: 'after', widget: 'dxButton', options: {
                        text: 'Cancel', onClick: function() {
        e.Customize("open", model)
    .dxrd-reportdialog-content .reportdialog-item.dx-texteditor:not(.dx-multiline):not(.dx-textarea) {
        height: 36px;
        margin-bottom: 10px;

<script type="text/html" id="open">
    <div class="dxrd-reportdialog-content">
        <div style="margin-bottom: 10px;" data-bind="dxTextBox: { height: 36, value: inputValue, 
             valueChangeEvent: 'keyup', placeholder: 'Enter text to search...', showClearButton: true }"></div>
        <div class="dx-default-border-style dxd-border-secondary" data-bind="dxList: {
                    dataSource: categories,
                    height: '260px',
                    grouped: true,
                    searchExpr: 'text',
                    searchValue: inputValue,
                    displayExpr: 'displayName',
                    keyExpr: 'text',
                    collapsibleGroups: true,

         .ClientSideEvents(configure => {
See Also