Hi,
I am working on a multiselect filter, where default "All" option should be removed
if the user selects something other than "All". The caviat is that the options for multiselect are
not based on a search, they are manually added. For example:
<choice value="first_choice="*"">All</choice>
<choice value="second_choice="Y"">second choice</choice>
<choice value="third_choice="Y"">third choice</choice>
<choice value="fourth_choice="Y"">fourth choice</choice>
<choice value="fifth_choice="Y"">fifth choice</choice>
What I usually do doesn't work:
<change>
<eval token="form.mytoken">if(mvcount('form.mytoken')=0,"*",if(mvcount('form.mytoken')!=1,mvfilter('form.mytoken'!="*"),'form.mytoken'))</eval>
</change>
If anyone has a solution, I would really appreciate it. Thank you!
Just cheat like this:
<input type="multiselect" token="hard_coded_list">
<label>hardcoded list</label>
<fieldForLabel>label</fieldForLabel>
<fieldForValue>value</fieldForValue>
<search>
<query>| makeresults | eval _raw="
value label
* All
second choice second choice
third_choice third choice
fourth_choice fourth choice
fifth_choice fifth choice"
| multikv forceheader=1</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
</search>
<change>
<eval token="form.hard_coded_list">case(mvcount($form.hard_coded_list$) == 2 AND mvindex($form.hard_coded_list$, 0) == "*", mvindex($form.hard_coded_list$, 1), mvfind($form.hard_coded_list$, "^\\*$") == mvcount($form.hard_coded_list$) - 1, "*", true(), $form.hard_coded_list$, false(), "BEWARE: THIS INPUT MUST NOT CONTAIN THE 'searchWhenChanged' FLAG!!!")</eval>
</change>
<default>*</default>
<prefix>sourcetype IN(</prefix>
<suffix>)</suffix>
<initialValue>*</initialValue>
<valuePrefix>"</valuePrefix>
<valueSuffix>"</valueSuffix>
<delimiter>,</delimiter>
</input>
Three things need to happen relating to "All" - if the selection is empty, put the default "All" in the form token; if "All" is added after another value, make the form token hold just "All"; and, if another value is added after "All", keep all values which aren't "All". Otherwise, keep the token as it is.
<change>
<eval token="form.mytoken">case(mvcount('form.mytoken')=0,"All",mvcount('form.mytoken')>1 AND mvfind('form.mytoken',"All")>0,"All",mvcount('form.mytoken')>1 AND mvfind('form.mytoken',"All")=0,mvfilter('form.mytoken'!="All"),1==1,'form.mytoken')</eval>
</change>
Note that the case function has to be all on one line in the dashboard code.
Hi,
Here with the same issue. When you mention "All" in the xml, you are not using the value "first_choice="*"" ?
<choice value="first_choice="*"">All</choice>
this is a default and initial value, where first_choice is an actual field in the search. the rest of the choices are also fields in the search. I'd expect to be using that. Here is an example
<eval token="form.mytoken">case(mvcount('form.mytoken')=0,"first_choice="*"",mvcount('form.mytoken')>1 AND mvfind('form.mytoken',"first_choice="*"")>0,"first_choice="*"",mvcount('form.mytoken')>1 AND mvfind('form.mytoken',"first_choice="*"")=0,mvfilter('form.mytoken'!="first_choice="*""),1==1,'form.mytoken')</eval>
But please correct me if that's not the case. I am trying to use the logic that you are showing here, and it makes sense, but it doesn't work with my example-the "ALL" option is still there even if i pick something else.
Thank you for helping out.
Try escaping the double quotes with backslash in the strings
<form version="1.1">
<label>Multiselect</label>
<fieldset submitButton="false" autoRun="true">
<input type="multiselect" token="alloptions" searchWhenChanged="true">
<label>Options ($optioncount$) $alloptions$</label>
<choice value="first_choice="*"">All</choice>
<choice value="second_choice="Y"">second choice</choice>
<choice value="third_choice="Y"">third choice</choice>
<choice value="fourth_choice="Y"">fourth choice</choice>
<choice value="fifth_choice="Y"">fifth choice</choice>
<delimiter>,</delimiter>
<change>
<eval token="optioncount">mvcount('form.alloptions')</eval>
<eval token="form.alloptions">case(mvcount('form.alloptions')=0,"first_choice=\"*\"",mvcount('form.alloptions')>1 AND mvfind('form.alloptions',"first_choice=\"*\"")>0,"first_choice=\"*\"",mvcount('form.alloptions')>1 AND mvfind('form.alloptions',"first_choice=\"*\"")=0,mvfilter('form.alloptions'!="first_choice=\"*\""),1==1,'form.alloptions')</eval>
</change>
</input>
</fieldset>
</form>
Be aware that <change> it not supported on multiselect inputs though and I vaguely remember finding a case where it didn't work, though lost in the depths of time
Are you sure about that, because I use this type of code with multiselect inputs in 8.2.2.1 and 9.0.4
Sure? No - not really other than that the docs state that in the inputs section
and some time ago I did have some particular use case, where some aspect of <change> did not work as expected, but for the life of me, I can't recall the exact behaviour and whether it was change+condition or something else.
So, I just started relying on the JS solution, as that works.
Try this (ignore documentation in this instance 😁)
<form version="1.1">
<label>Multiselect</label>
<fieldset submitButton="false" autoRun="true">
<input type="multiselect" token="alloptions" searchWhenChanged="true">
<label>Options ($optioncount$) $alloptions$</label>
<choice value="All">All</choice>
<search>
<query>
| makeresults count=10
| streamstats count as row
| eval option="Option ".mvindex(split("ABCDEFGHIJ",""),row-1)
| eval label="Option ".mvindex(split("abcdefghij",""),row-1)
| table option label
</query>
</search>
<fieldForLabel>label</fieldForLabel>
<fieldForValue>option</fieldForValue>
<delimiter>,</delimiter>
<change>
<eval token="optioncount">mvcount('form.alloptions')</eval>
<eval token="form.alloptions">case(mvcount('form.alloptions')=0,"All",mvcount('form.alloptions')>1 AND mvfind('form.alloptions',"All")>0,"All",mvcount('form.alloptions')>1 AND mvfind('form.alloptions',"All")=0,mvfilter('form.alloptions'!="All"),1==1,'form.alloptions')</eval>
</change>
</input>
</fieldset>
</form>
You need to do this with JS, so save this javascript into your_app/appserver/static folder and then in your dashboard set
<form script="multiselect.js"...>
and then in your input, do
<input type="multiselect" id="multi_1"...>
require([
'jquery',
'underscore',
'splunkjs/mvc',
'splunkjs/mvc/simplexml/ready!'
],
function($, _, mvc) {
var multi1 = mvc.Components.get("multi_1");
if (multi1 != null) {
multi1.on("change", function() {
var currentVal = multi1.val();
var first = multi1.options.choices[0].value;
if (currentVal.length > 1 && currentVal.indexOf(first) >= 0) {
multi1.val(_.without(currentVal, first));
}
else if (currentVal.length == 0) {
multi1.val(first);
}
});
}
});