All Apps and Add-ons

Why doesn't this JavaScript work to apply a click event to the Water Gauge Custom Viz?

jlemley
Path Finder

As a followup to "Water Gauge visualization Drilldown??"

Why would this code not apply the click event to my dashboard when it loads? If I run the JavaScript directly in the browser console, the click event is attached, and all is well.

The idea behind the JavaScript is that it will automatically apply a click event to every Water Gauge visualization on the dashboard as long as a drilldown option is added. My theory is that the jQuery that looks for the visualizations is firing too early (before the DOM is loaded), but I don't know of another way to grab the elements without hardcoding, as outlined in the above referenced question.

Dashboard:

<dashboard script="water_gauge_drilldown.js">
  <label>water gauge test</label>
  <row>
    <panel>
      <viz type="TA-ctl_splunk_it_one_viz.water_gauge">
        <search>
          <query>| makeresults | eval hi=55 | fields hi</query>
          <earliest>0</earliest>
          <latest></latest>
        </search>
        <option name="TA-ctl_splunk_it_one_viz.water_gauge.drilldown">http://google.com</option>
      </viz>
    </panel>
  </row>
</dashboard>

Note the required "drilldown" option entry in the Water Gauge XML to define the URL:

<option name="<viz_app>.water_gauge.drilldown">url_to_destination</option>

If the option is not found, the JavaScript will just return false and no action will be taken. Notice that this option is customized to my environment and may throw an error if it is not updated to match your environment.

JavaScript:

var components = [
      "splunkjs/ready!",
      "splunkjs/mvc/simplexml/ready!",
      "jquery"
];
require(components, function(
  mvc,
  ignored,
  $
) {
  $('.splunk-water-gauge').click(function(el) { 
    parent_el = $(this).parents('div[class^="dashboard-element viz"]')[0].id;
    viz_details = mvc.Components.getInstance(parent_el);
    if (typeof(parent_el) == 'undefined') { 
        return false; 
    }
    var url = viz_details.options.reportContent["display.visualizations.custom.TA-ctl_splunk_it_one_viz.water_gauge.drilldown"];
    if(typeof(url) == 'undefined') {
        return false;
    }
    window.open(url,'_blank');
  });
});
0 Karma
1 Solution

jlemley
Path Finder

After much research and trial & error, I believe the answer to this question is: Because the elements have not finished loading when this JavaScript code is run.

I tried several ways to work around this, including:

$(document).ready(function(){
$(document).bind("PageReady", function() {

And a few others.

But none of these methods ran after the Water Gauge element was created - likely because the visualization itself is built with JavaScript. I ended up wrapping the whole thing in a "setTimeout" block with a wait of 10s. This is a terrible hack, but it's the only way I could figure out to run the script after the water gauge was done loading.

I also attempted to use the native MVC click method instead of jQuery, but could not get the click event to fire. However, I did work around the hardcoded "options" variable, and now read it no matter where the Water Gauge lives in Splunk. Here is the code I finally ended up using:

setTimeout(function(){
    var components = [
          "splunkjs/ready!",
          "splunkjs/mvc/simplexml/ready!",
          "jquery",
          'splunkjs/mvc/utils'
    ];
    require(components, function(
      mvc,
      ignored,
      $,
      utils
    ) {
        $('.splunk-water-gauge').unbind();
        $('.splunk-water-gauge').click(function(el) {
            var re=/([\$].+?[\$])/g
            var url;
            var tokens = mvc.Components.get("submitted");
            parent_el = $(this).parents('div[class^="dashboard-element viz"]')[0].id;
            if (typeof(parent_el) == 'undefined') { 
                return false; 
            }
            viz_details = mvc.Components.getInstance(parent_el);
            var optionsArray = viz_details.options.reportContent;
            getOptionsKeys = Object.keys(optionsArray);
            getOptionsKeys.forEach(function(item) {
                if(item.indexOf("drilldown") != -1) {
                    url=optionsArray[item];
                }
            });
            if(typeof(url) == 'undefined') {
                return false;
            }
            var tokensArray=url.match(re);
            $(tokensArray).each(function(i,token) {
                clean_token=token.replace(/\$?/g,"");
                var tokenValue = tokens.get(clean_token);
                url=url.replace(token,tokenValue);
            });
            utils.redirect(url, false, "_blank");
        });
    });
}, 5000);

Edited to add token handling.

View solution in original post

0 Karma

jlemley
Path Finder

After much research and trial & error, I believe the answer to this question is: Because the elements have not finished loading when this JavaScript code is run.

I tried several ways to work around this, including:

$(document).ready(function(){
$(document).bind("PageReady", function() {

And a few others.

But none of these methods ran after the Water Gauge element was created - likely because the visualization itself is built with JavaScript. I ended up wrapping the whole thing in a "setTimeout" block with a wait of 10s. This is a terrible hack, but it's the only way I could figure out to run the script after the water gauge was done loading.

I also attempted to use the native MVC click method instead of jQuery, but could not get the click event to fire. However, I did work around the hardcoded "options" variable, and now read it no matter where the Water Gauge lives in Splunk. Here is the code I finally ended up using:

setTimeout(function(){
    var components = [
          "splunkjs/ready!",
          "splunkjs/mvc/simplexml/ready!",
          "jquery",
          'splunkjs/mvc/utils'
    ];
    require(components, function(
      mvc,
      ignored,
      $,
      utils
    ) {
        $('.splunk-water-gauge').unbind();
        $('.splunk-water-gauge').click(function(el) {
            var re=/([\$].+?[\$])/g
            var url;
            var tokens = mvc.Components.get("submitted");
            parent_el = $(this).parents('div[class^="dashboard-element viz"]')[0].id;
            if (typeof(parent_el) == 'undefined') { 
                return false; 
            }
            viz_details = mvc.Components.getInstance(parent_el);
            var optionsArray = viz_details.options.reportContent;
            getOptionsKeys = Object.keys(optionsArray);
            getOptionsKeys.forEach(function(item) {
                if(item.indexOf("drilldown") != -1) {
                    url=optionsArray[item];
                }
            });
            if(typeof(url) == 'undefined') {
                return false;
            }
            var tokensArray=url.match(re);
            $(tokensArray).each(function(i,token) {
                clean_token=token.replace(/\$?/g,"");
                var tokenValue = tokens.get(clean_token);
                url=url.replace(token,tokenValue);
            });
            utils.redirect(url, false, "_blank");
        });
    });
}, 5000);

Edited to add token handling.

0 Karma
Got questions? Get answers!

Join the Splunk Community Slack to learn, troubleshoot, and make connections with fellow Splunk practitioners in real time!

Meet up IRL or virtually!

Join Splunk User Groups to connect and learn in-person by region or remotely by topic or industry.

Get Updates on the Splunk Community!

[Puzzles] Solve, Learn, Repeat: Matching cron expressions

This puzzle (first published here) is based on matching timestamps to cron expressions.All the timestamps ...

Design, Compete, Win: Submit Your Best Splunk Dashboards for a .conf26 Pass

Hello Splunkers,  We’re excited to kick off a Splunk Dashboard contest! We know that dashboards are a primary ...

May 2026 Splunk Expert Sessions: Security & Observability

Level Up Your Operations: May 2026 Splunk Expert Sessions Whether you are refining your security posture or ...