You can use extensions to customize the HTML JavaScript Dashboard. The extension is an independent JavaScript module/class that provides specific functionality to the control.
This topic explains how to access the existing extensions, customize them, or create new extensions.
Get Underlying DashboardControl
You can customize the Web Dashboard before the underlying client part is rendered. For this, you need to get access to the DashboardControl instance. Use the BeforeRender event to configure the underlying part for wrappers (Web Forms, MVC, and ASP.NET Core controls). Refer to the following topics to learn how to obtain the DashboardControl:
For the HTML JavaScript control, configure the control before you call the render method:
window.onload = function () {
var dashboardControl = = new DevExpress.Dashboard.DashboardControl(document.getElementById("web-dashboard"), {
// Here you configure the control's options.
});
// Here you can customize a control.
dashboardControl.render();
}
Add or Remove Existing Extensions
To access all the enabled extensions, use the DashboardControl.extensions property that returns an array of objects. Each object implements the IExtension interface. The table below lists the Web Dashboard’s commonly used extensions:
Extension
| Description
|
---|
ToolboxExtension
| The Web Dashboard Toolbox extension that provides access to the dashboard menu and allows you to add dashboard items, as well as undo or repeat user actions.
|
DashboardParameterDialogExtension
| A Web Dashboard extension that is the Dashboard Parameters dialog.
|
DashboardExportExtension
| A Web Dashboard extension that allows you to export dashboards and dashboard items.
|
ViewerApiExtension
| An extension that allows you to customize a visual part of the Web Dashboard.
|
MobileLayoutExtension
| A Web Dashboard extension that allows you to enable a mobile layout for phones.
|
See the DevExpress.Dashboard.Designer module to find all available extensions.
Each extension exposes the IExtension.name property which returns an extension’s unique name. Use this name to access the extension.
To disable an extension, pass its name (IExtension.name) to the DashboardControl.unregisterExtension method. The code below shows how to disable the Web Dashboard’s export functionality:
function onBeforeRender(sender) {
// ...
var dashboardControl = sender.GetDashboardControl();
dashboardControl.unregisterExtension("dashboard-export");
}
window.onload = function () {
var dashboardControl = = new DevExpress.Dashboard.DashboardControl(document.getElementById("web-dashboard"), {
// ...
});
dashboardControl.unregisterExtension("dashboard-export");
dashboardControl.render();
}
Note that some extensions (for instance, DashboardPanelExtension) are disabled. The code below shows how to use the DashboardControl.registerExtension method to enable the Dashboard Panel:
function onBeforeRender(sender) {
// ...
var dashboardControl = sender.GetDashboardControl();
dashboardControl.registerExtension(new DevExpress.Dashboard.DashboardPanelExtension(dashboardControl));
}
Customize Existing Extension
To configure the registered extension, use the DashboardControl.findExtension method to obtain its instance and pass the IExtension.name property value as a method parameter.
The code sample below demonstrates how to use the ToolboxExtension.removeMenuItem method to obtain the ToolboxExtension and remove the New… command from the dashboard menu:
function onBeforeRender(sender) {
var dashboardControl = sender.GetDashboardControl();
var toolboxExtension = dashboardControl.findExtension("toolbox");
toolboxExtension.removeMenuItem("create-dashboard");
}
window.onload = function () {
var dashboardControl = = new DevExpress.Dashboard.DashboardControl(document.getElementById("web-dashboard"), {
// ...
});
var toolboxExtension = dashboardControl.findExtension("toolbox");
toolboxExtension.removeMenuItem("create-dashboard");
dashboardControl.render();
}
Example: How to Add Save As and Delete Functionality to the Web Dashboard
This example demonstrates how to add the “Save As” and “Delete” menu items to the Web Dashboard’s UI by implementing the corresponding custom extensions:
- The “Save As” menu item allows end-users to save the current dashboard with a new name.
- The “Delete” menu item deletes the opened dashboard from the dashboard storage.
The image below shows the result of the extensions implementation.
// Creates and implements a custom SaveAsDashboardExtension class.
function SaveAsDashboardExtension(dashboardControl) {
var _this = this;
this._control = dashboardControl;
this._toolbox = this._control.findExtension("toolbox");
this._newDashboardExtension = this._control.findExtension("create-dashboard");
this._menuItem = {
id: "dashboard-save-as",
title: "Save As...",
template: "dx-save-as-form",
selected: ko.observable(true),
disabled: ko.computed(function () { return !dashboardControl.dashboard(); }),
index: 112,
data: _this
};
this.saveAs = function () {
if (this.isExtensionAvailable()) {
this._toolbox.menuVisible(false);
this._newDashboardExtension.performCreateDashboard(this.newName(), this._control.dashboard().getJSON());
}
};
this.newName = ko.observable("New Dashboard Name");
}
SaveAsDashboardExtension.prototype.isExtensionAvailable = function () {
return this._toolbox !== undefined && this._newDashboardExtension !== undefined;
}
SaveAsDashboardExtension.prototype.start = function () {
if (this.isExtensionAvailable())
this._toolbox.menuItems.push(this._menuItem);
};
SaveAsDashboardExtension.prototype.stop = function () {
if (this.isExtensionAvailable())
this._toolbox.menuItems.remove(this._menuItem);
}
// Creates and implements a custom DeleteDashboardExtension class.
function DeleteDashboardExtension(_wrapper) {
var _this = this;
this._wrapper = _wrapper;
this._control = _wrapper.GetDashboardControl();
this._toolbox = this._control.findExtension('toolbox');
this.name = "dxdde-delete-dashboard";
this.deleteDashboard = function () {
if (_this.isExtensionAvailable()) {
if (confirm("Delete this Dashboard?")) {
var dashboardid = _this._control.dashboardContainer().id;
var param = JSON.stringify({ DashboardID: dashboardid, ExtensionName: _this.name });
_this._toolbox.menuVisible(false);
_this._wrapper.PerformDataCallback(param, function () {
_this._control.close();
});
}
}
}
this._menuItem = {
id: this.name,
title: "Delete",
click: this.deleteDashboard,
selected: ko.observable(false),
disabled: ko.computed(function () { return !_this._control.dashboard(); }),
index: 113,
hasSeparator: true,
data: _this
};
}
DeleteDashboardExtension.prototype.isExtensionAvailable = function () {
return this._toolbox !== undefined;
}
DeleteDashboardExtension.prototype.start = function () {
if (this.isExtensionAvailable())
this._toolbox.menuItems.push(this._menuItem);
};
DeleteDashboardExtension.prototype.stop = function () {
if (this.isExtensionAvailable())
this._toolbox.menuItems.remove(this._menuItem);
};
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AspDashboard_CustomExtension.Default" %>
<%@ Register Assembly="DevExpress.Dashboard.v17.1.Web, Version=17.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.DashboardWeb" TagPrefix="dx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<script type="text/javascript" src="Scripts/SaveAsExtension.js"></script>
<script type="text/javascript" src="Scripts/DeleteExtension.js"></script>
<!-- Defines the "Save As" extension template. -->
<script type="text/html" id="dx-save-as-form">
<div>Dashboard Name:</div>
<div style="margin: 10px 0" data-bind="dxTextBox: { value: newName }"></div>
<div data-bind="dxButton: { text: 'Save', onClick: saveAs }"></div>
</script>
<script type="text/javascript">
function onBeforeRender(sender) {
var control = sender.GetDashboardControl();
control.registerExtension(new SaveAsDashboardExtension(control));
control.registerExtension(new DeleteDashboardExtension(sender));
}
</script>
<form id="form1" runat="server">
<div style="position: absolute; top: 0; bottom: 0; left: 0; right: 0;">
<dx:ASPxDashboard ID="ASPxDashboard1" ClientInstanceName="dashboard" runat="server"
UseDashboardConfigurator="true"
OnCustomDataCallback="ASPxDashboard1_CustomDataCallback"
WorkingMode="Designer"
Width="100%" Height="100%">
<ClientSideEvents BeforeRender="onBeforeRender" />
</dx:ASPxDashboard>
</div>
</form>
</body>
</html>
using Storages;
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
namespace AspDashboard_CustomExtension {
public partial class Default : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
}
protected void ASPxDashboard1_CustomDataCallback(object sender, DevExpress.Web.CustomDataCallbackEventArgs e) {
Dictionary<string, string> parameters = new JavaScriptSerializer().Deserialize<Dictionary<string, string>>(e.Parameter);
if (!parameters.ContainsKey("ExtensionName"))
return;
CustomDashboardFileStorage newDashboardStorage = new CustomDashboardFileStorage(@"~/App_Data/Dashboards");
if (parameters["ExtensionName"] == "dxdde-delete-dashboard" && parameters.ContainsKey("DashboardID"))
newDashboardStorage.DeleteDashboard(parameters["DashboardID"]);
}
}
}
using DevExpress.DashboardWeb;
using System.IO;
namespace Storages {
public class CustomDashboardFileStorage : DashboardFileStorage {
public CustomDashboardFileStorage(string workingDirectory)
: base(workingDirectory) {
}
public void DeleteDashboard(string dashboardID) {
var dashboardPath = base.ResolveFileName(dashboardID);
if (File.Exists(dashboardPath))
File.Delete(dashboardPath);
}
}
}
<%@ Page Language="vb" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="AspDashboard_CustomExtension.Default" %>
<%@ Register Assembly="DevExpress.Dashboard.v17.1.Web, Version=17.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.DashboardWeb" TagPrefix="dx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<script type="text/javascript" src="Scripts/SaveAsExtension.js"></script>
<script type="text/javascript" src="Scripts/DeleteExtension.js"></script>
<!-- Defines the "Save As" extension template. -->
<script type="text/html" id="dx-save-as-form">
<div>Dashboard Name:</div>
<div style="margin: 10px 0" data-bind="dxTextBox: { value: newName }"></div>
<div data-bind="dxButton: { text: 'Save', onClick: saveAs }"></div>
</script>
<script type="text/javascript">
function onBeforeRender(sender) {
var control = sender.GetDashboardControl();
control.registerExtension(new SaveAsDashboardExtension(control));
control.registerExtension(new DeleteDashboardExtension(sender));
}
</script>
<form id="form1" runat="server">
<div style="position: absolute; top: 0; bottom: 0; left: 0; right: 0;">
<dx:ASPxDashboard ID="ASPxDashboard1" ClientInstanceName="dashboard" runat="server"
UseDashboardConfigurator="true"
OnCustomDataCallback="ASPxDashboard1_CustomDataCallback"
WorkingMode="Designer"
Width="100%" Height="100%">
<ClientSideEvents BeforeRender="onBeforeRender" />
</dx:ASPxDashboard>
</div>
</form>
</body>
</html>
Imports Storages
Imports System
Imports System.Collections.Generic
Imports System.Web.Script.Serialization
Namespace AspDashboard_CustomExtension
Partial Public Class [Default]
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Protected Sub ASPxDashboard1_CustomDataCallback(ByVal sender As Object, ByVal e As DevExpress.Web.CustomDataCallbackEventArgs)
Dim parameters As Dictionary(Of String, String) = (New JavaScriptSerializer()).Deserialize(Of Dictionary(Of String, String))(e.Parameter)
If Not parameters.ContainsKey("ExtensionName") Then
Return
End If
Dim newDashboardStorage As New CustomDashboardFileStorage("~/App_Data/Dashboards")
If parameters("ExtensionName") = "dxdde-delete-dashboard" AndAlso parameters.ContainsKey("DashboardID") Then
newDashboardStorage.DeleteDashboard(parameters("DashboardID"))
End If
End Sub
End Class
End Namespace
Imports DevExpress.DashboardWeb
Imports System.IO
Namespace Storages
Public Class CustomDashboardFileStorage
Inherits DashboardFileStorage
Public Sub New(ByVal workingDirectory As String)
MyBase.New(workingDirectory)
End Sub
Public Sub DeleteDashboard(ByVal dashboardID As String)
Dim dashboardPath = MyBase.ResolveFileName(dashboardID)
If File.Exists(dashboardPath) Then
File.Delete(dashboardPath)
End If
End Sub
End Class
End Namespace
See Also