Dashboards & Visualizations
Highlighted

How do I eval a token initially and on input change based on another token?

Champion

My goal is to set a time token to something ahead of the actual earliest value set in a time input on dashboard load (and whenever the time input changes of course), based on some other input on that dashboard. To do that, I set up an eval inside the change event of my time input where I would use some magic with relative_time, with the relative time coming from another input on the dashboard. See this example dashboard:

<form>
  <label>time input change on dashboard load using third token</label>
  <fieldset submitButton="false">
    <input type="time" token="time_tok" searchWhenChanged="true">
      <label>Time</label>
      <default>
        <earliest>-15m</earliest>
        <latest>now</latest>
      </default>
      <change>
        <!-- This would've been where relative_time comes in, left out to simplify things -->
        <eval token="setToken.earliest">'offset_token'</eval>
        <eval token="setToken.latest">"-1h"</eval>
      </change>
    </input>
    <input type="text" token="offset_token" searchWhenChanged="true">
      <label>token input</label>
      <default>-2h</default>
      <change>
        <eval token="setToken.earliest">'offset_token'</eval>
      </change>
    </input>
  </fieldset>
  <row>
    <panel>
      <table>
        <title>set from $setToken.earliest$ to $setToken.latest$, originally $time_tok.earliest$ to $time_tok.latest$</title>
        <search>
          <query>index=_internal | head 100 | stats count by group</query>
          <earliest>$setToken.earliest$</earliest>
          <latest>$setToken.latest$</latest>
        </search>
        <option name="wrap">undefined</option>
        <option name="rowNumbers">undefined</option>
        <option name="drilldown">row</option>
      </table>
    </panel>
  </row>
</form>

You'll notice that the search doesn't run on dashboard load, which is because the token "setToken.earliest" is not yet set. When you change the time input after the dashboard has loaded, everything works fine. Debugging the js that runs on change of the input reveals that the token model does not yet contain a token by the name of "offset_token" when the initial change of the time input is called, only when you manually change the input after the dashboard has loaded is that token available.

I know that in Splunk 6.5, you can set tokens to initial values on dashboard load, but at the moment that is not available to me. How am I supposed to go about using the value of another token to initially set a token? I have a not-so-pretty solution coming up, but I would be happy to see another, more clever one.

0 Karma
Highlighted

Re: How do I eval a token initially and on input change based on another token?

Champion

So I thought I had a solution, but it turns out it doesn't quite work. The idea was to set the "setToken.earliest" token to the same value that the other token has by default (i.e. hard-coding the default value) and use that value if the offset token wasn't available, like so:

<form>
  <label>time input change on dashboard load using third token</label>
  <fieldset submitButton="false">
    <input type="time" token="time_tok" searchWhenChanged="true">
      <label>Time</label>
      <default>
        <earliest>-15m</earliest>
        <latest>now</latest>
      </default>
      <change>
        <eval token="setToken.earliest">if(isnull('offset_token'), "-2h", 'offset_token')</eval>
        <eval token="setToken.latest">"-1h"</eval>
      </change>
    </input>
    <input type="text" token="offset_token" searchWhenChanged="true">
      <label>token input</label>
      <default>-2h</default>
      <change>
        <eval token="setToken.earliest">'offset_token'</eval>
      </change>
    </input>
  </fieldset>
  <row>
    <panel>
      <table>
        <title>set from $setToken.earliest$ to $setToken.latest$, originally $time_tok.earliest$ to $time_tok.latest$</title>
        <search>
          <query>index=_internal | head 100 | stats count by group</query>
          <earliest>$setToken.earliest$</earliest>
          <latest>$setToken.latest$</latest>
        </search>
        <option name="wrap">undefined</option>
        <option name="rowNumbers">undefined</option>
        <option name="drilldown">row</option>
      </table>
    </panel>
  </row>
</form>

But now the fun starts. The dashboard doesn't work, debugging reveals that the token is evaluated correctly during the change event:
alt text
But after that, when the rest of the js has finished, the token is gone again:
alt text
At this point, I don't know why this fails.

0 Karma
Highlighted

Re: How do I eval a token initially and on input change based on another token?

SplunkTrust
SplunkTrust

I don't see where setToken is defined. Is there supposed to be a third input, hidden, to accept the values from the other two?

0 Karma
Highlighted

Re: How do I eval a token initially and on input change based on another token?

Champion

The token "setToken" is not used in any input, it just lives on its own as a token when created in either of the inputs.

0 Karma
Highlighted

Re: How do I eval a token initially and on input change based on another token?

Champion

I found it. In the second input, you can't use the token yet, but you can use 'value' or $value$ to get that value:

<form>
  <label>time input change on dashboard load using third token</label>
  <fieldset submitButton="false">
    <input type="time" token="time_tok" searchWhenChanged="true">
      <label>Time</label>
      <default>
        <earliest>-15m</earliest>
        <latest>now</latest>
      </default>
      <change>
        <eval token="setToken.earliest">if(isnull('offset_token'), "-2h", 'offset_token')</eval>
        <eval token="setToken.latest">"-1h"</eval>
      </change>
    </input>
    <input type="text" token="offset_token" searchWhenChanged="true">
      <label>token input</label>
      <default>-2h</default>
      <change>
        <eval token="setToken.earliest">'value'</eval>
      </change>
    </input>
  </fieldset>
  <row>
    <panel>
      <table>
        <title>set from $setToken.earliest$ to $setToken.latest$, originally $time_tok.earliest$ to $time_tok.latest$</title>
        <search>
          <query>index=_internal | head 100 | stats count by group</query>
          <earliest>$setToken.earliest$</earliest>
          <latest>$setToken.latest$</latest>
        </search>
        <option name="wrap">undefined</option>
        <option name="rowNumbers">undefined</option>
        <option name="drilldown">row</option>
      </table>
    </panel>
  </row>
</form>

This works, but I don't like it. The default value of the offset token hard-coded in a second place, so if you change the default value of the input that sets the offset token you'll end up with inconsistent token values until you manually set either the time or the input token for the first time.
I'd appreciate better ideas!

0 Karma