Dashboards & Visualizations

How to show a dashboard panel- only if one or more input token is set?

VexenCrabtree
Path Finder

I have a dashboard with some user inputs at the top (IP, hostname, asset ID, etc), and two search panels work correctly when any of the fields are populated. So far, so simple. But when NONE of the inputs are filled out, I don't want the searches to run.

I need something like:

<panel depends="$input1$ OR $input2$ OR $input3$ or $input4$'">

Once thing I've tried is to concatenate all inputs into one large messy string. On all 4 inputs, I've tried this:

<input type="text" token="field1" searchWhenChanged="true">
    <change>
         <eval token="somethingToShow">$input1$+$input2$+$input3$+$input4$</eval>
      ...
<!-- and then, later:-->
<panel depends="$somethingToShow$">

However, even when all the inputs are blank, the panel still shows. This is because although $somethingToShow$ is an empty string, it isn't unset.

I also tried using a "$countOfInputs" variable which on is set to 0, and whenever input is entered, increments, and whenever input is set to ="", then to decrements. But the problem was that I still couldn't unset it when it was 0. I tried using a hidden input field which I could increment or decrement, and then use to on that value=0. But I couldn't get an input field to be hidden from the user.

Questions:

  1. How do you apply <depends> to more than one token?
  2. How do you unset a token only if multiple other tokens are blank?
  3. Is there an overall event, that is invoked when ANY token changes, so that I can unset a token there if all the fields are blank? I can't find any examples of this kind of thing so I guess not.

I've been working on this simple concept most of yesterday and today, and have gone through a large number of docs/Splunk answer articles... this is one of those things that is probably too simple to have been spelled out anywhere!

0 Karma
1 Solution

VexenCrabtree
Path Finder

The answer: Use an independent token ('somethingToShow') which defaults to unset, and which gets set if any input field is set to non-blank, using logic in .

On I've created a token called "somethingToShow", which

<form>
  <init>
     <unset token="lSomethingToShow"></unset>

And my panel uses depends, therefore, is initially hidden:

<panel depends="$lSomethingToShow$">

When any field changes, I run logic to see if ALL inputs are blank, and if so, it also unsets SomethingToShow:

<input type="text" token="pIP" searchWhenChanged="true">
  <change>
    <condition match='$pIP$=="" AND $pHost$=="" AND ... ... ... '>
      <unset token="lSomethingToShow"></unset>
      ....... OTHER STUFF .....
    </condition>
    .... OTHER STUFF....
    <condition><!-- Earlier conditions is for blank values, so, this default one is for a non-blank value-->
      <set token="lSomethingToShow"></set>

So, voila, the panel only appears if 1 or more of the inputs is set.

Initial question is answered.

However.

The next difficulty is that the form accepts parameters from other dashboards via drilldown links. When the Dashboard loads, it correctly fills out the passed values, but it does NOT run the condition for the initial values, therefore, the panel isn't showing even when it should. I'll ask a new question: how do you make the run for the initial value passed from a URL parameter?

View solution in original post

0 Karma

VexenCrabtree
Path Finder

The answer: Use an independent token ('somethingToShow') which defaults to unset, and which gets set if any input field is set to non-blank, using logic in .

On I've created a token called "somethingToShow", which

<form>
  <init>
     <unset token="lSomethingToShow"></unset>

And my panel uses depends, therefore, is initially hidden:

<panel depends="$lSomethingToShow$">

When any field changes, I run logic to see if ALL inputs are blank, and if so, it also unsets SomethingToShow:

<input type="text" token="pIP" searchWhenChanged="true">
  <change>
    <condition match='$pIP$=="" AND $pHost$=="" AND ... ... ... '>
      <unset token="lSomethingToShow"></unset>
      ....... OTHER STUFF .....
    </condition>
    .... OTHER STUFF....
    <condition><!-- Earlier conditions is for blank values, so, this default one is for a non-blank value-->
      <set token="lSomethingToShow"></set>

So, voila, the panel only appears if 1 or more of the inputs is set.

Initial question is answered.

However.

The next difficulty is that the form accepts parameters from other dashboards via drilldown links. When the Dashboard loads, it correctly fills out the passed values, but it does NOT run the condition for the initial values, therefore, the panel isn't showing even when it should. I'll ask a new question: how do you make the run for the initial value passed from a URL parameter?

View solution in original post

0 Karma

tomawest
Path Finder

Hi,

  1. Look at the option with inputs. Further info for this can be found in the docs here

2 and 3: You're after some advanced token logic. I have an example dashboard which may be of use. In essence I use hidden text fields to set the values of multiple tokens and replicate logic throughout without having loads of set and unset statements all over the place.

<form script="tokenlinks.js">
  <label>Button Handler Updated</label>
  <!--
  <init>
    <set token="ShowDev"></set>
  </init>
  -->
  <fieldset submitButton="false"></fieldset>
  <row>
    <panel depends="$ShowBoth$">
      <html>
        <button class="btn" data-set-token="form.DateButton" data-value="Show">Show Date</button>
        <button class="btn" data-set-token="form.SecsButton" data-value="Show">Show Time</button>
        <button class="btn" data-set-token="form.AllButton" data-value="Show">Show All</button>
      </html>
    </panel>
    <panel depends="$ShowDate$">
      <html>
        <button class="btn" data-set-token="form.DateButton" data-value="Show">Show Date</button>
        <button class="btn" data-set-token="form.SecsButton" data-value="">Hide Time</button>
        <button class="btn" data-set-token="form.AllButton" data-value="Show">Show All</button>
      </html>
    </panel>
    <panel depends="$ShowSecs$">
      <html>
        <button class="btn" data-set-token="form.DateButton" data-value="">Hide Date</button>
        <button class="btn" data-set-token="form.SecsButton" data-value="Show">Show Time</button>
        <button class="btn" data-set-token="form.AllButton" data-value="Show">Show All</button>
      </html>
    </panel>
    <panel depends="$ShowHide$">
      <html>
        <button class="btn" data-set-token="form.DateButton" data-value="">Hide Date</button>
        <button class="btn" data-set-token="form.SecsButton" data-value="">Hide Time</button>
      </html>
    </panel>
  </row>
  <row>
    <panel>
      <single depends="$ShowDatePanel$">
        <search>
          <query>
            | makeresults | eval ShowMessage=strftime(now(),"%b %e") | fields ShowMessage
          </query>
        </search>
        <option name="rangeColors">["0x53a051","0x0877a6","0xf8be34","0xf1813f","0xdc4e41"]</option>
        <option name="underLabel">Date</option>
      </single>
      <single depends="$ShowSecsPanel$">
        <search>
          <query>
            | makeresults $ShowSecsPanel$ | eval ShowMessage=strftime(now(),"%H:%M:%S") | fields ShowMessage
          </query>
        </search>
        <option name="drilldown">all</option>
        <option name="rangeColors">["0x53a051","0x0877a6","0xf8be34","0xf1813f","0xdc4e41"]</option>
        <option name="underLabel">Time</option>
        <drilldown>
          <set token="form.SecsButton"></set>
        </drilldown>
      </single>
      <html rejects="$ShowBoth$">
        <button class="btn" data-set-token="form.AllButton" data-value="">Hide All</button>
      </html>
    </panel>
  </row>
  <row depends="$ShowDev$">
    <panel>
      <html>
        <h1>DEV CONTROLS</h1>
      </html>
    </panel>
  </row>
  <row depends="$ShowDev$">
    <panel>
      <input type="text" token="DateButton">
        <default></default>
        <change>
          <condition value="Show">
            <set token="ShowDatePanel"></set>
            <set token="form.SetButtonsInitial">DateShow</set>
            <set token="form.AllButton">Date</set>
          </condition>
          <condition>
            <unset token="ShowDatePanel"></unset>
            <set token="form.SetButtonsInitial">DateHide</set>
            <set token="form.AllButton">Date</set>
          </condition>
        </change>
      </input>
      <input type="text" token="SecsButton">
        <default></default>
        <change>
          <condition value="Show">
            <set token="ShowSecsPanel"></set>
            <set token="form.SetButtonsInitial">SecsShow</set>
            <set token="form.AllButton">Secs</set>
          </condition>
          <condition>
            <unset token="ShowSecsPanel"></unset>
            <set token="form.SetButtonsInitial">SecsHide</set>
            <set token="form.AllButton">Secs</set>
          </condition>
        </change>
      </input>
      <input type="text" token="AllButton">
        <default></default>
        <change>
          <condition value="Show">
            <set token="form.SecsButton">Show</set>
            <set token="form.DateButton">Show</set>
          </condition>
          <condition value="Date"></condition>
          <condition value="Secs"></condition>
          <condition>
            <set token="form.SecsButton"></set>
            <set token="form.DateButton"></set>
          </condition>
        </change>
      </input>
      <input type="text" token="SetButtonsInitial">
        <default></default>
        <change>
          <condition match="$form.SecsButton$==&quot;Show&quot; AND $form.DateButton$==&quot;Show&quot;">
            <set token="form.ResetButtons"></set>
          </condition>
          <condition match="$form.SecsButton$==&quot;Show&quot;">
            <set token="form.ResetButtons">Secs</set>
          </condition>
          <condition match="$form.DateButton$==&quot;Show&quot;">
            <set token="form.ResetButtons">Date</set>
          </condition>
          <condition>
            <set token="form.ResetButtons">Both</set>
          </condition>
        </change>
      </input>
      <input type="text" token="ResetButtons">
        <default></default>
        <change>
          <unset token="ShowBoth"></unset>
          <unset token="ShowSecs"></unset>
          <unset token="ShowDate"></unset>
          <unset token="ShowHide"></unset>
          <set token="form.SetButtons">$value$</set>
        </change>
      </input>
      <input type="text" token="SetButtons">
        <default></default>
        <change>
          <condition value="Both">
            <set token="ShowBoth"></set>
          </condition>
          <condition value="Secs">
            <set token="ShowDate"></set>
          </condition>
          <condition value="Date">
            <set token="ShowSecs"></set>
          </condition>
          <condition>
            <set token="ShowHide"></set>
          </condition>
        </change>
      </input>
    </panel>
  </row>
</form>

The tokenlinks js file is the same file you can get from the dashboard examples app. The code is below, however its just to handle the buttons in the same way any other input sets a token value.

require(['jquery', 'underscore', 'splunkjs/mvc', 'util/console'], function($, _, mvc, console) {

    function setToken(name, value) {
        console.log('Setting Token %o=%o', name, value);

        var defaultTokenModel = mvc.Components.get('default');
        if (defaultTokenModel) {
            defaultTokenModel.set(name, value);
        }
        var submittedTokenModel = mvc.Components.get('submitted');
        if (submittedTokenModel) {
            submittedTokenModel.set(name, value);
        }
    }

    $('.dashboard-body').on('click', '[data-set-token],[data-unset-token],[data-token-json]', function(e) {
        e.preventDefault();
        var target = $(e.currentTarget);

        var setTokenName = target.data('set-token');
        if (setTokenName) {
            setToken(setTokenName, target.data('value'));
        }

        var unsetTokenName = target.data('unset-token');
        if (unsetTokenName) {
            setToken(unsetTokenName, undefined);
        }

        var tokenJson = target.data('token-json');
        if (tokenJson) {
            try {
                if (_.isObject(tokenJson)) {
                    _(tokenJson).each(function(value, key) {
                        if (value == null) {
                            // Unset the token
                            setToken(key, undefined);
                        } else {
                            setToken(key, value);
                        }
                    });
                }
            } catch (e) {
                console.warn('Cannot parse token JSON: ', e);
            }
        }
    });

});
0 Karma

VexenCrabtree
Path Finder

(1) I've been over the Inputs doc you linked quite a lot. What section are you saying applies?

(2) I haven't got that .js file on my system, and I can't add it (I don't have permissions).

(3) I've been trying to follow the logic of your code (i.e., using $ShowBoth$) to see how it works; it looks like all the action is user-driven (i.e., then press buttons to show/hide different elements). What I need is for the searches to run only if any input (at the top of the form) is filled out, but without the user having to manually click "show this bit". In your code, where's the bit that checks if tokens have non-blank values, and then, sets or unsets after making that comparison?

0 Karma
Take the 2021 Splunk Career Survey

Help us learn about how Splunk has
impacted your career by taking the 2021 Splunk Career Survey.

Earn $50 in Amazon cash!