Skip to main content

Dashboard Item Description - Custom Property

  • 4 minutes to read

This extension enables you to set a description for each dashboard item. The dashboard item description is displayed when you hover the info button in the item’s caption.

This extension:

  • Adds a custom string property for each dashboard item.
  • Integrates a Description (Custom) section in the Options menu with the predefined buttonGroup template.
  • Shows how to enable or disable editors depending on a custom property’s value.

Every extension that provides a custom property can be divided to the following parts:

Model

The model is a CustomPropertyMetadata object that contains the property name, type, and the default value. It also specifies on which level the property is created (a dashboard, dashboard item or data item container). Use the Model.registerCustomProperty property to register the custom property definition.

var ItemDescriptionExtension = (function () {
    var Model = DevExpress.Dashboard.Model;

    // 1. Model
    var enabledProperty = {
        ownerType: Model.DashboardItem,
        propertyName: "descriptionEnabled",
        defaultValue: false,
        valueType: 'boolean'
    };
    var textProperty = {
        ownerType: Model.DashboardItem,
        propertyName: "description",
        defaultValue: "",
        valueType: 'string'
    };
    var displayModeProperty = {
        ownerType: Model.DashboardItem,
        propertyName: "descriptionDisplayMode",
        defaultValue: 'Always',
        valueType: 'string'
    };

    Model.registerCustomProperty(enabledProperty);
    Model.registerCustomProperty(displayModeProperty);
    Model.registerCustomProperty(textProperty);

    return ItemDescriptionExtension;
}());

Viewer

In this part, you modify the viewer according to the saved custom property value. You can use the client methods and events to change the displayed elements. To display a non-default icon for a new toolbar button, register the SVG icon in the resource manager (the registerIcon(icon) property). The icon is added by its ID from the definition (iconDescription).

var ItemDescriptionExtension = (function () {
    var Dashboard = DevExpress.Dashboard;

    // The SVG icon's definition.
    var svgIcon = '<svg version="1.1" id="iconDescription" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve"><style type="text/css">.dx-dashboard-icon {fill:currentColor;}</style><path class="dx-dashboard-icon" d="M12,3c-5,0-9,4-9,9s4,9,9,9s9-4,9-9S17,3,12,3z M12,19c-3.9,0-7-3.1-7-7s3.1-7,7-7s7,3.1,7,7S15.9,19,12,19z M12,17L12,17c-0.6,0-1-0.4-1-1v-5c0-0.6,0.4-1,1-1l0,0c0.6,0,1,0.4,1,1v5C13,16.6,12.6,17,12,17zM12,9L12,9c-0.6,0-1-0.4-1-1l0,0c0-0.6,0.4-1,1-1l0,0c0.6,0,1,0.4,1,1l0,0C13,8.6,12.6,9,12,9z"/></svg>';

    // Register the icon.
    Dashboard.ResourceManager.registerIcon(svgIcon);

    // 2. Viewer
    function onItemCaptionToolbarUpdated(args) {
        var descriptionVisible = args.dashboardItem.customProperties.getValue(enabledProperty.propertyName);
        if (descriptionVisible) {
            var description = args.dashboardItem.customProperties.getValue(textProperty.propertyName);
            var displayMode = args.dashboardItem.customProperties.getValue(displayModeProperty.propertyName);
            var array = displayMode === 'OnHover' ? args.options.actionItems : args.options.stateItems;
            array.push({
                type: "button",
                icon: "iconDescription",
                tooltip: !!description ? description.toString() : undefined
            });
        }
    };
    function isDescriptionDisabled(dashboardItem) {
        return !dashboardItem.customProperties.getValue(enabledProperty.propertyName);
    }
    function changeDisabledState(dxForm, fieldName, isDisabled) {
        let itemOptions = dxForm.itemOption(fieldName)
        if(itemOptions) {
            let editorOptions = itemOptions.editorOptions || {}
            editorOptions.disabled = isDisabled
            dxForm.itemOption(fieldName, "editorOptions", editorOptions)
        }
    }

    return ItemDescriptionExtension;
}());

Designer

This part contains designer settings. Add editors and control elements to configure and change the custom property’s values in the UI. This part is not required if you use the extension in Viewer mode or do not want to let users edit a custom property’s value. For this custom property, integrates a Description (Custom) section in the Options menu. You can use the predefined buttonGroup template to create button groups.

var ItemDescriptionExtension = (function () {
    var Designer = DevExpress.Dashboard.Designer;

    // 3. Designer
    // Checks whether to enable or disable editors.
    function isDescriptionDisabled(dashboardItem) {
        return !dashboardItem.customProperties.getValue(enabledProperty.propertyName);
    }

    // Enables or disables editors.
    function changeDisabledState(dxForm, fieldName, isDisabled) {
        let itemOptions = dxForm.itemOption(fieldName)
        if(itemOptions) {
            let editorOptions = itemOptions.editorOptions || {}
            editorOptions.disabled = isDisabled
            dxForm.itemOption(fieldName, "editorOptions", editorOptions)
        }
    }
    // Adds a new section.
    function onCustomizeSections(args) {
        args.addSection({
            title: "Description (Custom)",
            onFieldDataChanged: function (e) { 
                e.component.beginUpdate();
                changeDisabledState(e.component, textProperty.propertyName, isDescriptionDisabled(args.dashboardItem));
                changeDisabledState(e.component, displayModeProperty.propertyName, isDescriptionDisabled(args.dashboardItem));
                e.component.endUpdate();
            },
            items: [
                {
                    dataField: enabledProperty.propertyName,
                    label: {
                        text: "Visible"
                    },
                    template: Designer.FormItemTemplates.buttonGroup,
                    editorOptions: {
                        keyExpr: "value",
                        items: [{
                            value: true,
                            text: "Visible"
                        }, {
                            value: false,
                            text: "Hidden"
                        }]
                    }
                },
                {
                    dataField: displayModeProperty.propertyName,
                    label: {
                        text: "Display Mode"
                    },
                    template: Designer.FormItemTemplates.buttonGroup,
                    editorOptions: {
                        keyExpr: "value",
                        items: [{
                            value: "OnHover",
                            text: "On hover"
                        }, {
                            value: "Always",
                            text: "Always"
                        }],
                        disabled: isDescriptionDisabled(args.dashboardItem)
                    }
                },
                {
                    dataField: textProperty.propertyName,
                    editorType: "dxTextArea",
                    label: {
                        text: "Description"
                    },
                    editorOptions: {
                        height: 90,
                        disabled: isDescriptionDisabled(args.dashboardItem)
                    }
                }
            ]
        });
    };

    return ItemDescriptionExtension;
}());

Event Subscription

This part contains event subscriptions. In this example, it is the ViewerApiExtensionOptions.onItemCaptionToolbarUpdated and OptionsPanelExtensionOptions.onCustomizeSections events.

var ItemDescriptionExtension = (function () {

    // 4. Event Subscription
    function ItemDescriptionExtension(dashboardControl) {
        this.name = "ItemDescription";
        this.start = function () {
            var viewerApiExtension = dashboardControl.findExtension('viewerApi');
            if (viewerApiExtension) {
                viewerApiExtension.on('itemCaptionToolbarUpdated', onItemCaptionToolbarUpdated);
            }
            var optionsPanelExtension = dashboardControl.findExtension("itemOptionsPanel");
            if (optionsPanelExtension) {
                optionsPanelExtension.on('customizeSections', onCustomizeSections);
            }
        };
        this.stop = function () {
            var viewerApiExtension = dashboardControl.findExtension('viewerApi');
            if (viewerApiExtension) {
                viewerApiExtension.off('itemCaptionToolbarUpdated', onItemCaptionToolbarUpdated);
            }
            var optionsPanelExtension = dashboardControl.findExtension("itemOptionsPanel");
            if (optionsPanelExtension) {
                optionsPanelExtension.off('customizeSections', onCustomizeSections);
            }
        };
    }

    return ItemDescriptionExtension;
}());