Can I Use A Custom Interactive Filter to Filter Multiple Tables?

Robert Campbell
Tera Guru

I have a dashboard that shows different aspects of services, incidents, releases, changes and outages. I have a custom interactive filter that gives the count of incidents based on partial service name using the script below. I would like to update that script so that it will impact the count of services, releases, changes and outages as well. Is there a way to make this work against multiple tables?

 

 

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
&lt;script&gt;
var my_dashboardMessageHandler = new DashboardMessageHandler("name");

function publishFilter () {
	var filter_message = {};
	filter_message.id = "name";
	filter_message.table = "incident";
	var value = gel('cfName').value;
	filter_message.filter = "business_serviceLIKE" + value;
	SNC.canvas.interactiveFilters.setDefaultValue({
		id: filter_message.id,
		filters: [filter_message]
	}, false);
	my_dashboardMessageHandler.publishFilter(filter_message.table, filter_message.filter);
}

function clearFilter() {
	var filter_message = {};
	filter_message.id = "name";
	filter_message.table = "incident";
	filter_message.filter = "";
	gel('cfName').value = '';
	SNC.canvas.interactiveFilters.setDefaultValue({
		id: filter_message.id,
		filters: [filter_message]
	}, false);
	my_dashboardMessageHandler.removeFilter();
}
&lt;/script&gt;

Name:
<input id="cfName" type="input" value="" /><br/>
<input id="removeCustomFilter" type="button" value="Clear" onclick="clearFilter();" />
<input id="addCustomFilter" type="button" value="Search" onclick="publishFilter();" />
</j:jelly>

 

 

1 ACCEPTED SOLUTION

Robert Campbell
Tera Guru

I tried multiple things. I tried creating one function that called each function but that didn't work. I called the next function from the current function but that didn't work. Finally I broke down and phoned a friend and we came up with:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide">
<script>
    // Create a unique DashboardMessageHandler for each table
    var dashboardHandlers = {
        incident: new DashboardMessageHandler("incidentHandler"),
        cmdb_ci_service: new DashboardMessageHandler("cmdbHandler"),
        rm_release: new DashboardMessageHandler("releaseHandler"),
        change_request: new DashboardMessageHandler("changeHandler")
    };

    // Generic function to apply a filter
    function applyFilter(handler, table, filter) {
        var filter_message = {
            id: table + "_filter", // Unique ID for each table
            table: table,
            filter: filter
        };

        SNC.canvas.interactiveFilters.setDefaultValue({
            id: filter_message.id,
            filters: [filter_message]
        }, false);

        handler.publishFilter(filter_message.table, filter_message.filter);
        console.log("Filter applied to '" + table + "': " + filter_message.filter);
    }

    // Main function to trigger all filters
    function publishAllFilters() {
        var value = gel('cfName').value.trim(); // Get input value
        if (!value) {
            alert("Please enter a value to filter.");
            return;
        }
        console.log("Applying filters with value: " + value);

        // Apply filters for each table
        applyFilter(dashboardHandlers.incident, "incident", "business_serviceLIKE" + value);
        applyFilter(dashboardHandlers.cmdb_ci_service, "cmdb_ci_service", "nameLIKE" + value);
        applyFilter(dashboardHandlers.rm_release, "rm_release", "parent.cmdb_ciLIKE" + value);
        applyFilter(dashboardHandlers.change_request, "change_request", "business_serviceLIKE" + value);

        console.log("All filters applied successfully.");
    }

    // Function to clear all filters
    function clearFilter() {
        var value = gel('cfName').value = ''; // Clear input field
        Object.keys(dashboardHandlers).forEach(function (key) {
            var handler = dashboardHandlers[key];
            handler.removeFilter();
            console.log("Filters cleared for table: " + key);
        });
    }
</script>

<!-- Input and Buttons -->
Name:
<input id="cfName" type="text" value="" /><br/>
<input id="removeCustomFilter" type="button" value="Clear" onclick="clearFilter();" />
<input id="addCustomFilter" type="button" value="Search" onclick="publishAllFilters();" />
</j:jelly>

 

This works.  Oddly, I have to run it multiple times for it to work sometimes.

View solution in original post

3 REPLIES 3

How can we achieve such wizardry once dashboards are migrated to platform analytics?

The DashboardMessageHandler - publishMessage() method supports sending an array of filters in a single message.

Xanadu Documentation including example code is available here: https://www.servicenow.com/docs/bundle/xanadu-now-intelligence/page/app-store/dev_portal/API_referen... .

Robert Campbell
Tera Guru

I tried multiple things. I tried creating one function that called each function but that didn't work. I called the next function from the current function but that didn't work. Finally I broke down and phoned a friend and we came up with:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide">
<script>
    // Create a unique DashboardMessageHandler for each table
    var dashboardHandlers = {
        incident: new DashboardMessageHandler("incidentHandler"),
        cmdb_ci_service: new DashboardMessageHandler("cmdbHandler"),
        rm_release: new DashboardMessageHandler("releaseHandler"),
        change_request: new DashboardMessageHandler("changeHandler")
    };

    // Generic function to apply a filter
    function applyFilter(handler, table, filter) {
        var filter_message = {
            id: table + "_filter", // Unique ID for each table
            table: table,
            filter: filter
        };

        SNC.canvas.interactiveFilters.setDefaultValue({
            id: filter_message.id,
            filters: [filter_message]
        }, false);

        handler.publishFilter(filter_message.table, filter_message.filter);
        console.log("Filter applied to '" + table + "': " + filter_message.filter);
    }

    // Main function to trigger all filters
    function publishAllFilters() {
        var value = gel('cfName').value.trim(); // Get input value
        if (!value) {
            alert("Please enter a value to filter.");
            return;
        }
        console.log("Applying filters with value: " + value);

        // Apply filters for each table
        applyFilter(dashboardHandlers.incident, "incident", "business_serviceLIKE" + value);
        applyFilter(dashboardHandlers.cmdb_ci_service, "cmdb_ci_service", "nameLIKE" + value);
        applyFilter(dashboardHandlers.rm_release, "rm_release", "parent.cmdb_ciLIKE" + value);
        applyFilter(dashboardHandlers.change_request, "change_request", "business_serviceLIKE" + value);

        console.log("All filters applied successfully.");
    }

    // Function to clear all filters
    function clearFilter() {
        var value = gel('cfName').value = ''; // Clear input field
        Object.keys(dashboardHandlers).forEach(function (key) {
            var handler = dashboardHandlers[key];
            handler.removeFilter();
            console.log("Filters cleared for table: " + key);
        });
    }
</script>

<!-- Input and Buttons -->
Name:
<input id="cfName" type="text" value="" /><br/>
<input id="removeCustomFilter" type="button" value="Clear" onclick="clearFilter();" />
<input id="addCustomFilter" type="button" value="Search" onclick="publishAllFilters();" />
</j:jelly>

 

This works.  Oddly, I have to run it multiple times for it to work sometimes.