Dashboards & Visualizations

How to Set and Unset a token conditionally when other tokens must always be set from the same input

weidertc
Communicator

I have a Time selector. Each time it's clicked, a certain set of tokens must always recalculate, including one which determines the span of time in between earliest and latest.

I have 2 panels. Only 1 panel must be shown at a time, depending on how long the span is between earliest and latest. Within 1 day, show the "comparison" panel, longer than 1 day, show the "single" panel

The xml below always sets both tokens, "showPanelSingle" and "showPanelComparison", but I can only have 1 set at a time.

<input type="time" token="time" searchWhenChanged="false">
  <label>Time Frame</label>
  <default>
    <earliest>-1d@d</earliest>
    <latest>@d</latest>
  </default>
  <change>
    <eval token="time.earliest_epoch">if(isnum('earliest'),'earliest',relative_time(now(),'earliest'))</eval>
    <eval token="time.latest_epoch">if(isnum('latest'),'latest',relative_time(now(),'latest'))</eval>
    <eval token="time_difference">$time.latest_epoch$-$time.earliest_epoch$</eval>
    <eval token="form.span">if($time_difference$&gt;2592000,"1d",if($time_difference$&gt;86400,"1h","1m"))</eval>
    <eval token="showPanel">if($time_difference$&gt;86400,"Comparison","Single")</eval>
    <eval token="showPanelSingle">if($showPanel$="Single","true","")</eval>
    <eval token="showPanelComparison">if($showPanel$="Comparison","true","")</eval>
  </change>
</input>

The xml below never sets either token, even after selecting the Time.

<form theme="dark">
  <label></label>
  <init>
    <condition match="$showPanel$, &quot;Single&quot;">
      <eval token="showPanelSingle">true</eval>
    </condition>
    <condition match="$showPanel$, &quot;Comparison&quot;">
      <eval token="showPanelComparison">true</eval>
    </condition>
  </init>

Note, the Time calculations must always run, so I can't add them to a condition, but I need condition on the rest, and Splunk doesn't allow this hybrid approach, nor is it allowed to qualify multiple condition tags.

How can I accomplish where 1 and only 1 of them is set (and the correct one) upon clicking "Submit" in the input filters.

0 Karma
1 Solution

weidertc
Communicator

This can be accomplished by saving the value of showPanel in another input field, such as a dropdown.

<input type="time" token="time" searchWhenChanged="false">
  <label>Time Frame</label>
  <default>
    <earliest>-1d@d</earliest>
    <latest>@d</latest>
  </default>
  <change>
    <eval token="time.earliest_epoch">if(isnum('earliest'),'earliest',relative_time(now(),'earliest'))</eval>
    <eval token="time.latest_epoch">if(isnum('latest'),'latest',relative_time(now(),'latest'))</eval>
    <eval token="time_difference">$time.latest_epoch$-$time.earliest_epoch$</eval>
    <eval token="form.span">if($time_difference$>2592000,"1d",if($time_difference$>86400,"1h","1m"))</eval>
    <eval token="form.panel">if($time_difference$<=86400,"compare","single")</eval>

In the last line, "panel" is the token name for the input panel below and automatically selects its dropdown value.

Now that we've isolated the value, we can apply the familiar set of conditions how it's usually done.

<input type="dropdown" token="panel" depends="$neverShow$">
  <label>Panel</label>
  <choice value="single">Single</choice>
  <choice value="compare">Compare</choice>
  <change>
    <condition value="compare">
      <unset token="showPanelSingle"></unset>
      <set token="showPanelComparison">true</set>
    </condition>
    <condition value="single">
      <unset token="showPanelComparison"></unset>
      <set token="showPanelSingle">true</set>
    </condition>
  </change>
</input>

Adding a "depends" on the input panel hides it from view so no one knows it's there. You can assign it any token, but it should be one that doesn't exist so it will never get set. The panel still runs and the selection will determine what token gets set.

Now the tokens are conditionally set and I always only get 1 panel showing.

View solution in original post

weidertc
Communicator

This can be accomplished by saving the value of showPanel in another input field, such as a dropdown.

<input type="time" token="time" searchWhenChanged="false">
  <label>Time Frame</label>
  <default>
    <earliest>-1d@d</earliest>
    <latest>@d</latest>
  </default>
  <change>
    <eval token="time.earliest_epoch">if(isnum('earliest'),'earliest',relative_time(now(),'earliest'))</eval>
    <eval token="time.latest_epoch">if(isnum('latest'),'latest',relative_time(now(),'latest'))</eval>
    <eval token="time_difference">$time.latest_epoch$-$time.earliest_epoch$</eval>
    <eval token="form.span">if($time_difference$>2592000,"1d",if($time_difference$>86400,"1h","1m"))</eval>
    <eval token="form.panel">if($time_difference$<=86400,"compare","single")</eval>

In the last line, "panel" is the token name for the input panel below and automatically selects its dropdown value.

Now that we've isolated the value, we can apply the familiar set of conditions how it's usually done.

<input type="dropdown" token="panel" depends="$neverShow$">
  <label>Panel</label>
  <choice value="single">Single</choice>
  <choice value="compare">Compare</choice>
  <change>
    <condition value="compare">
      <unset token="showPanelSingle"></unset>
      <set token="showPanelComparison">true</set>
    </condition>
    <condition value="single">
      <unset token="showPanelComparison"></unset>
      <set token="showPanelSingle">true</set>
    </condition>
  </change>
</input>

Adding a "depends" on the input panel hides it from view so no one knows it's there. You can assign it any token, but it should be one that doesn't exist so it will never get set. The panel still runs and the selection will determine what token gets set.

Now the tokens are conditionally set and I always only get 1 panel showing.

niketn
Legend

@weidertc seems like you tried two options. Both needs some tweaking and solve two different purpose:

  1. Within <time> input the <change> event handler can be used with <eval> along with case() to set a value based on condition otherwise set to null. With if() it can be used to set any value otherwise. However, both of these will not perform <unset>

Following is the code sample correction if null value is required for no match in condition:

     <eval token="showPanelSingle">case($showPanel$=="Single","true")</eval>
     <eval token="showPanelComparison">case($showPanel$=="Comparison","true")</eval>
  1. The <init> section is invoked only once when the dashboard loads so it will not respond to any event handler /token changes. You can use and independent search to set the required token through Search Event Handler by passing the modified token to the Search. This forces search to re-execute every time the token is changed and accordingly the search event handler sets/unsets the token:

Following is the code sample for independent search:

  <search>
    <query>| makeresults
    | fields - _time
    | eval showPanel="$showPanel$"
    </query>
    <done>
     <condition match="$result.showPanel$==&quot;Single&quot;">
       <set token="showPanelSingle">true</set>
       <unset token="showPanelComparison"></unset>
     </condition>
     <condition match="$result.showPanel$==&quot;Comparison&quot;">
       <unset token="showPanelSingle"></unset>
       <set token="showPanelComparison">true</set>
     </condition>
    </done>
  </search>

PS: If you are not using showPanel token for any purpose other than setting /unsetting the showPanelSingle or showPanelComparison, then it is not required. You can take similar decision directly from $time_difference$ by passing it to the independent search

Please try out as per need and confirm!

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

weidertc
Communicator

Thanks for the suggestion. That indeed sets the value as null as I originally intended.

Unfortunately, it sets it at all, so it doesn't solve the problem and both queries still run.

I did actually find a hacky way to accomplish this. I'll post it as an answer.

It's really bazaar how Splunk doesn't allow you to run a set of evals AND apply conditions afterward, and further a more versatile way to unset a token.

0 Karma
Get Updates on the Splunk Community!

Index This | I am a number, but when you add ‘G’ to me, I go away. What number am I?

March 2024 Edition Hayyy Splunk Education Enthusiasts and the Eternally Curious!  We’re back with another ...

What’s New in Splunk App for PCI Compliance 5.3.1?

The Splunk App for PCI Compliance allows customers to extend the power of their existing Splunk solution with ...

Extending Observability Content to Splunk Cloud

Register to join us !   In this Extending Observability Content to Splunk Cloud Tech Talk, you'll see how to ...