Dashboards & Visualizations

How to dynamically select items in a multiselect input

jimrp
Engager

Hi Splunkers,

I'm trying to build my first dashboard and I've hit a wall, I can't find any mention of this elsewhere, can anyone help?

 

I'm trying to make a multiselect input with all elements from a search, and dynamically select 10 of them (based on a field in the search).

 

I get a list of all the elements in the list from: 

index=* 
| fields spID
| dedup spID

I can get the ones I want selected using:

index=* 
| stats count(spID) as auths by spID
| sort -auths limit=10

(this then spills over into a chart)

the code I have so far is:

<input type="multiselect" token="spPicker" searchWhenChanged="true">
<label>spPicker</label>
<fieldForLabel>spID</fieldForLabel>
<fieldForValue>spID</fieldForValue>
<valuePrefix>"</valuePrefix>
<valueSuffix>"</valueSuffix>
<search>
<query>index=*
| fields spID
| dedup spID</query>
<earliest>$field1.earliest$</earliest>
<latest>$field1.latest$</latest>
</search>
<delimiter>,</delimiter>
</input>

So this half works - all the elements are present in the list. I don't see a way of auto selecting the top 10 - I've tried <defaults> and <initialValues>, but these both want a static list. Any ideas anyone?

 

thanks in advance,

 

Jim

 

 

Labels (3)
0 Karma
1 Solution

ITWhisperer
SplunkTrust
SplunkTrust

This is not an easy one and this may still not work as there appears to be some issues with timing. However, I got this to work reasonably reliably:

    <input type="multiselect" token="alloptions" searchWhenChanged="true">
      <label>Options</label>
      <search>
        <query>
| makeresults count=20
| streamstats count as row
| eval option="Option ".mvindex(split("ABCDEFGHIJKLMNOPQRSTUVWXYZ",""),row-1)
| table option
        </query>
      </search>
      <fieldForLabel>option</fieldForLabel>
      <fieldForValue>option</fieldForValue>
    </input>
    <input type="multiselect" token="tenoptions" searchWhenChanged="true" depends="$alwayshide$">
      <label>Options $optionsresult$</label>
      <search>
        <query>
| makeresults count=20
| streamstats count as row
| eval option="Option ".mvindex(split("ABCDEFGHIJKLMNOPQRSTUVWXYZ",""),row-1)
| where row%2=0
| stats values(option) as option
        </query>
        <done>
          <eval token="form.alloptions">$result.option$</eval>
          <eval token="optionsresult">mvjoin($result.option$,",")</eval>
        </done>
      </search>
      <fieldForLabel>option</fieldForLabel>
      <fieldForValue>option</fieldForValue>
    </input>

Essentially, what is happening is this.

The second multiselect is hidden (depends="$alwayshide$").

Both multiselects use the same basis search, however, the search for the second multiselect filters out to just ten results, which it puts in a multi-value field.

This is so that there is only one row in the results with all the values to be preselected.

The done handler for the search then sets the form token for the first multiselect to the multivalue field from the results.

It also sets another token with the mutilselect joined by commas.

This is use in the label of the hidden multiselect.

This appears to be important (at least in my test environment) as it appears to slow down this part so that the first multiselect has completed initialisation before this happens, allowing the preset to work.

If this isn't done, the preset does still work but is then over-written by the initialisation sequence of the first multiselect.

View solution in original post

0 Karma

ITWhisperer
SplunkTrust
SplunkTrust

This is not an easy one and this may still not work as there appears to be some issues with timing. However, I got this to work reasonably reliably:

    <input type="multiselect" token="alloptions" searchWhenChanged="true">
      <label>Options</label>
      <search>
        <query>
| makeresults count=20
| streamstats count as row
| eval option="Option ".mvindex(split("ABCDEFGHIJKLMNOPQRSTUVWXYZ",""),row-1)
| table option
        </query>
      </search>
      <fieldForLabel>option</fieldForLabel>
      <fieldForValue>option</fieldForValue>
    </input>
    <input type="multiselect" token="tenoptions" searchWhenChanged="true" depends="$alwayshide$">
      <label>Options $optionsresult$</label>
      <search>
        <query>
| makeresults count=20
| streamstats count as row
| eval option="Option ".mvindex(split("ABCDEFGHIJKLMNOPQRSTUVWXYZ",""),row-1)
| where row%2=0
| stats values(option) as option
        </query>
        <done>
          <eval token="form.alloptions">$result.option$</eval>
          <eval token="optionsresult">mvjoin($result.option$,",")</eval>
        </done>
      </search>
      <fieldForLabel>option</fieldForLabel>
      <fieldForValue>option</fieldForValue>
    </input>

Essentially, what is happening is this.

The second multiselect is hidden (depends="$alwayshide$").

Both multiselects use the same basis search, however, the search for the second multiselect filters out to just ten results, which it puts in a multi-value field.

This is so that there is only one row in the results with all the values to be preselected.

The done handler for the search then sets the form token for the first multiselect to the multivalue field from the results.

It also sets another token with the mutilselect joined by commas.

This is use in the label of the hidden multiselect.

This appears to be important (at least in my test environment) as it appears to slow down this part so that the first multiselect has completed initialisation before this happens, allowing the preset to work.

If this isn't done, the preset does still work but is then over-written by the initialisation sequence of the first multiselect.

0 Karma

jimrp
Engager

Hi ITWhisperer,

 

OK - I got that working eventually - thanks!

So my main comment here is how difficult this is to do - isn't this a pretty common scenario? I simplified my actual requirements here hugely - I'd like load of the dashboard elements to affect each other. I'll write up some notes and link them.

 

thanks again everyone!

 

Jim

 

0 Karma

tshah-splunk
Splunk Employee
Splunk Employee

Hey @jimrp,

There is one more workaround that you can try. Instead of one input, you can have two dynamic multi-select inputs defined. One of them with the top 10 values and the other one with the rest. And then in the query, you can include tokens from both the inputs and perform OR operation between them.  I don't have much background in custom javascript and am not sure if it can be helpful to achieve the objective. In this way, you can also achieve the case for selecting the top 10 values or any other value for spID field.

---
If you find the answer helpful, an upvote/karma is appreciated
0 Karma

tshah-splunk
Splunk Employee
Splunk Employee

Hey @jimrp,

You can achieve this by statically keeping initial and default values to *

This will work only if you want the top 10 values in the input. You can place below query in the search for dynamic input as you mentioned to achieve desired input

index=* 
| stats count(spID) as auths by spID
| sort -auths limit=10

Along with this, you can set Key to be All and its Value to be *. This will always have top 10 values auto-selected. But you won't be able to have other values to be present in the input. Your XML source code should look something like below:

<input type="multiselect" token="spPicker" searchWhenChanged="true">
<label>spPicker</label>
<fieldForLabel>spID</fieldForLabel>
<fieldForValue>spID</fieldForValue>
<valuePrefix>"</valuePrefix>
<valueSuffix>"</valueSuffix>
<search>
<query>index=*
| fields spID
| dedup spID</query>
<earliest>$field1.earliest$</earliest>
<latest>$field1.latest$</latest>
</search>
<delimiter>,</delimiter>
<choice value="*">All</choice>
</input>
---
If you find the answer helpful, an upvote/karma is appreciated
0 Karma

jimrp
Engager

Hi @tshah-splunk, thanks for getting back to me on this!

 

I've tried what you suggested - its close but not exactly what I wanted - I want all the items in the list, not just the top 10.

So if I can't do this with the simple XML dashboard option, are there alternative more complex dashboard building options available? I think I've seen mention of Javascript being used in dashboards (not quite sure how), is what I am asking even possible? If so, any suggestions welcome.

 

thanks again all,

 

JimRP

0 Karma
Get Updates on the Splunk Community!

Introduction to Splunk Observability Cloud - Building a Resilient Hybrid Cloud

Introduction to Splunk Observability Cloud - Building a Resilient Hybrid Cloud  In today’s fast-paced digital ...

Observability protocols to know about

Observability protocols define the specifications or formats for collecting, encoding, transporting, and ...

Take Your Breath Away with Splunk Risk-Based Alerting (RBA)

WATCH NOW!The Splunk Guide to Risk-Based Alerting is here to empower your SOC like never before. Join Haylee ...