- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there,
I have a dashboard that is populated with 4 inputs.
- Data type drop down with static list - this is the main filter
- multivalue selection based on case statement
- Text input box
- Time range picker
Basically I want a save button so that when a user filters data by data type(input 1) it remembers all the other settings for that data type(all the other input criteria like time, text input etc). So in a list of say 10 data types, each time i click on one of them it will remember the last settings that were saved(Basically state capture) to make it efficient when opening the panel.
Ideally stored in the kv store..
I have checked out this: https://answers.splunk.com/answers/617305/how-can-i-give-the-to-the-users-to-save-their-sele.html
Which gave me a brief understanding of how to do it, but not how to do it with everything based on remembering data input 1's settings.
Anyone know how to accomplish this?
Thanks
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I like @niketn's original solution, but I figured I'd throw my hat into the ring since it looks like @mwdbhyat might still be facing some issues.
Here is how I would tackle this particular problem. The solution assumes the following:
- The configuration settings are based on a dropdown input's selection
- Multivalue field, text input, and time-range picker should be populate based on the dropdown selection.
The following type of static data is used for demo purposes:
- Time: A specific time range consisting of earliest and latest time.
- Car Type: A specific brand of car e.g. Ford, Chevy, Honda etc. This field is the dropdown. Based on the
car's type, the other values are populated accordingly.
- Car Model: Model of a specific type of car, e.g. Ford F150, or Honda Accord.
- Car Color: Should be self explanatory 🙂
Define a KVstore in 'collections.conf' called 'dashboard_input_settings':
[dashboard_input_settings]
field.car_type = string
field.car_model = string
field.car_color = string
field.time_earliest = string
field.time_latest = string
field.saved_at = string
In the 'collections.conf' car_type, car_model, car_color, time_earliest, time_latest are all based on values
that are provided through the inputs on the dashboard.
The value of 'saved_at' will contain the _time of when the configuration is saved to ensure we can sort and
then dedup older values. This way we wont have duplicate configurations for one 'car_type'.
Define a lookup definition for the KVstore in 'transforms.conf':
[dashboard_input_settings]
collection = dashboard_input_settings
external_type = kvstore
fields_list = _key,car_type,car_model,car_color,time_earliest,time_latest,saved_at
Define the dashboard -- (with tons of comments, yay!):
<!-- load in the JavaScript file -->
<form script="input_settings.js">
<!--
On dashboard init, set the check_settings token to true so we can immediately check if the dropdowns value has a configuration
This token is 'depended' on for the 'check_for_saved_settings_search' to run below
-->
<init>
<set token="check_settings">true</set>
</init>
<label>Demo</label>
<!-- This search saves the configuration to the KVstore. It depends on all the necessary tokens being set before running. -->
<search id="save_dashboard_settings_search" depends="$save_config$,$time_tok.earliest$,$time_tok.latest$,$car_model_tok$,$car_type_tok$,$car_color_tok$">
<!--
The search looks up the current values in the KVstore's lookup definition, appends our new values to the bottom, and uses makeresults to
fake a new row result which adds a _time field. We set the saved_at to the _time (now), which we then use to sort the results newest to oldest, dedup them
which removes the oldest results ensuring no duplicate entries so it effectively 'updates' any pre-existing results, or appends a new result if a specific
'car_type' doesn't exist
-->
<query>
| inputlookup dashboard_input_settings | append [| makeresults | eval saved_at=_time | eval time_earliest="$time_tok.earliest$" | eval time_latest="$time_tok.latest$" | eval car_model="$car_model_tok$" | eval car_type="$car_type_tok$" | eval car_color="$car_color_tok$"] | fields - _time | sort 0 - saved_at | dedup car_type | outputlookup dashboard_input_settings
</query>
</search>
<!-- Check if the currently selected 'car_type' dropdown has a saved configuration in the KVstore. -->
<search id="check_for_saved_settings_search" depends="$car_type_tok$,$check_settings$">
<!--
The search checks to see if a specific 'car_type' selected in our dropdown exists in the KVstore. If it does, then ouput the necessary values for
that particular 'car_type'
-->
<query>
| inputlookup dashboard_input_settings WHERE car_type="$car_type_tok$" | table car_model, car_color, time_earliest, time_latest
</query>
<!-- When the search is finalized, we check if a result is returned or not -->
<finalized>
<!-- If one result is returned, then set the necessary tokens -->
<condition match="'job.resultCount' == 1">
<set token="form.time_tok.earliest">$result.time_earliest$</set>
<set token="form.time_tok.latest">$result.time_latest$</set>
<!-- 'car_model_tok' is not set here as its a multi-valued field, which is handled in the JavaScript -->
<set token="form.car_color_tok">$result.car_color$</set>
<unset token="check_settings"></unset>
</condition>
<!--
If no results are returned that means we have no configuration defined for the 'car_type' dropdown so we will unset
tokens and then set a default time for the timepicker
-->
<condition match="'job.resultCount' == 0">
<set token="form.time_tok.earliest">-24h</set>
<set token="form.time_tok.latest">now</set>
<unset token="form.car_model_tok"></unset>
<unset token="form.car_color_tok"></unset>
<unset token="check_settings"></unset>
</condition>
</finalized>
</search>
<!-- Input fields -->
<fieldset submitButton="false">
<input id="timepicker" type="time" token="time_tok" searchWhenChanged="true">
<label>Time Range</label>
<default>
<earliest>-24h@h</earliest>
<latest>now</latest>
</default>
</input>
<input type="dropdown" token="car_type_tok" searchWhenChanged="true">
<label>Car Type</label>
<choice value="ford">Ford</choice>
<choice value="chevy">Chevy</choice>
<choice value="honda">Honda</choice>
<choice value="toyota">Toyota</choice>
<choice value="tesla">Tesla</choice>
<change>
<set token="check_settings">true</set>
</change>
</input>
<input type="multiselect" token="car_model_tok" id="car_model_multiselect">
<label>Car Model</label>
<choice value="tahoe">Tahoe</choice>
<choice value="impala">Impala</choice>
<choice value="escape">Escape</choice>
<choice value="taurus">Taurus</choice>
<choice value="f150">F-150</choice>
<choice value="accord">Accord</choice>
<choice value="pilot">Pilot</choice>
<choice value="passport">Passport</choice>
<choice value="civic">Civic</choice>
<choice value="rav4">Rav4</choice>
<choice value="corolla">Corolla</choice>
<choice value="model3">Model3</choice>
<choice value="modelS">ModelS</choice>
<choice value="modelX">modelX</choice>
<delimiter> </delimiter>
</input>
<input type="text" token="car_color_tok">
<label>Car Color</label>
</input>
</fieldset>
</form>
Next, create the JavaScript file called 'input_settings.js' in the appserver/static folder of whatever app you're working in.
require(
[
'jquery',
'splunkjs/mvc'
],
function ($, mvc) {
// Create an instance of the save button
const save_config_button = $(`<button id="saveConfigButton" class="btn btn-primary">Save Configuration</button>`);
// Success message indicating config was saved
const success_message = $(`
<div id="successMessage" style="padding: 10px; background: #5cc05c; color: #FFFFFF; display: none">
Successfully saved the configuration!
</div>`);
// Instance of submitted tokens otherwise known as $form.tok$ in dashboard
const submitted_tokens = mvc.Components.get('submitted');
// Instance of the multiselect -- we need this to populate it from the KV store when we retrieve the settings
const car_model_multiselect = mvc.Components.get('car_model_multiselect');
// Instances of searches in our dashboard referenced by their ids
const save_dashboard_settings_search = mvc.Components.get('save_dashboard_settings_search');
const check_for_saved_settings_search = mvc.Components.get('check_for_saved_settings_search');
/*
* Get the results of a matching setting in the KV. This search is called on the dashboard init event
* as well as when the multi-valued field 'car_model_multiselect' is selected
*/
const check_for_saved_settings_results = check_for_saved_settings_search.data("results", {count: 0});
// Append the button to the dashboard
$('.dashboard-form-globalfieldset').append(save_config_button);
// Handle the click event on the save_config_button
save_config_button.on('click', function () {
// Disable it while the save action is occurring
save_config_button.prop('disabled', true);
// Change the text of the button to indicate its saving
save_config_button.text('Saving...');
/*
Sets the save_config token so that the 'save_dashboard_settings_search' runs -- this is
referenced in the depends of the 'save_dashboard_settings_search' e.g. depends="$save_config$"
*/
submitted_tokens.set({'save_config': true});
// Now run the search to save the settings
save_dashboard_settings_search.startSearch();
});
// Listen for the search to complete
save_dashboard_settings_search.on('search:done', function () {
// Re-enable the save button
save_config_button.prop('disabled', false);
// Change the text back to default
save_config_button.text('Save Configuration');
// Prepend the success message
$('.dashboard-form-globalfieldset').prepend(success_message);
// Success message hidden by default - fade it in over 1 second, show for 3 seconds, then fade out 1 sec.
success_message.fadeIn(1000).delay(3000).fadeOut(1000);
// Unset the 'save_config' token so the save config search doesn't unintentionally run
submitted_tokens.unset('save_config');
});
/*
* Wait for the check_for_saved_settings_results search to get data
*/
check_for_saved_settings_results.on("data", function () {
// Get the results of data
let rows = check_for_saved_settings_results.data().rows;
// Loops through the results
rows.forEach(function (row) {
// Turn result into an array
let car_models = row[0].split(' ');
// Populate the multi-select with the value of all the models
car_model_multiselect.val(car_models);
});
});
});
There is also a full demo app for this on Github here: https://github.com/deviansg/splunk_dashboard_input_settings in case you'd like to just have a working version to base everything off of.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Why is this necessary? The token values are stored as URIs on your URL so you can just bookmark any set of values at any time and return to them via bookmark. Isn't that good enough?
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Storing user settings on the server can serve different purposes than having them on the client. You could find arguments in favor of one or the other, I don't see how either method is superior. If having them on the client is "good enough" for you, then by all means do that - I'm still thankful for the effort @splunkian has put in.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I like @niketn's original solution, but I figured I'd throw my hat into the ring since it looks like @mwdbhyat might still be facing some issues.
Here is how I would tackle this particular problem. The solution assumes the following:
- The configuration settings are based on a dropdown input's selection
- Multivalue field, text input, and time-range picker should be populate based on the dropdown selection.
The following type of static data is used for demo purposes:
- Time: A specific time range consisting of earliest and latest time.
- Car Type: A specific brand of car e.g. Ford, Chevy, Honda etc. This field is the dropdown. Based on the
car's type, the other values are populated accordingly.
- Car Model: Model of a specific type of car, e.g. Ford F150, or Honda Accord.
- Car Color: Should be self explanatory 🙂
Define a KVstore in 'collections.conf' called 'dashboard_input_settings':
[dashboard_input_settings]
field.car_type = string
field.car_model = string
field.car_color = string
field.time_earliest = string
field.time_latest = string
field.saved_at = string
In the 'collections.conf' car_type, car_model, car_color, time_earliest, time_latest are all based on values
that are provided through the inputs on the dashboard.
The value of 'saved_at' will contain the _time of when the configuration is saved to ensure we can sort and
then dedup older values. This way we wont have duplicate configurations for one 'car_type'.
Define a lookup definition for the KVstore in 'transforms.conf':
[dashboard_input_settings]
collection = dashboard_input_settings
external_type = kvstore
fields_list = _key,car_type,car_model,car_color,time_earliest,time_latest,saved_at
Define the dashboard -- (with tons of comments, yay!):
<!-- load in the JavaScript file -->
<form script="input_settings.js">
<!--
On dashboard init, set the check_settings token to true so we can immediately check if the dropdowns value has a configuration
This token is 'depended' on for the 'check_for_saved_settings_search' to run below
-->
<init>
<set token="check_settings">true</set>
</init>
<label>Demo</label>
<!-- This search saves the configuration to the KVstore. It depends on all the necessary tokens being set before running. -->
<search id="save_dashboard_settings_search" depends="$save_config$,$time_tok.earliest$,$time_tok.latest$,$car_model_tok$,$car_type_tok$,$car_color_tok$">
<!--
The search looks up the current values in the KVstore's lookup definition, appends our new values to the bottom, and uses makeresults to
fake a new row result which adds a _time field. We set the saved_at to the _time (now), which we then use to sort the results newest to oldest, dedup them
which removes the oldest results ensuring no duplicate entries so it effectively 'updates' any pre-existing results, or appends a new result if a specific
'car_type' doesn't exist
-->
<query>
| inputlookup dashboard_input_settings | append [| makeresults | eval saved_at=_time | eval time_earliest="$time_tok.earliest$" | eval time_latest="$time_tok.latest$" | eval car_model="$car_model_tok$" | eval car_type="$car_type_tok$" | eval car_color="$car_color_tok$"] | fields - _time | sort 0 - saved_at | dedup car_type | outputlookup dashboard_input_settings
</query>
</search>
<!-- Check if the currently selected 'car_type' dropdown has a saved configuration in the KVstore. -->
<search id="check_for_saved_settings_search" depends="$car_type_tok$,$check_settings$">
<!--
The search checks to see if a specific 'car_type' selected in our dropdown exists in the KVstore. If it does, then ouput the necessary values for
that particular 'car_type'
-->
<query>
| inputlookup dashboard_input_settings WHERE car_type="$car_type_tok$" | table car_model, car_color, time_earliest, time_latest
</query>
<!-- When the search is finalized, we check if a result is returned or not -->
<finalized>
<!-- If one result is returned, then set the necessary tokens -->
<condition match="'job.resultCount' == 1">
<set token="form.time_tok.earliest">$result.time_earliest$</set>
<set token="form.time_tok.latest">$result.time_latest$</set>
<!-- 'car_model_tok' is not set here as its a multi-valued field, which is handled in the JavaScript -->
<set token="form.car_color_tok">$result.car_color$</set>
<unset token="check_settings"></unset>
</condition>
<!--
If no results are returned that means we have no configuration defined for the 'car_type' dropdown so we will unset
tokens and then set a default time for the timepicker
-->
<condition match="'job.resultCount' == 0">
<set token="form.time_tok.earliest">-24h</set>
<set token="form.time_tok.latest">now</set>
<unset token="form.car_model_tok"></unset>
<unset token="form.car_color_tok"></unset>
<unset token="check_settings"></unset>
</condition>
</finalized>
</search>
<!-- Input fields -->
<fieldset submitButton="false">
<input id="timepicker" type="time" token="time_tok" searchWhenChanged="true">
<label>Time Range</label>
<default>
<earliest>-24h@h</earliest>
<latest>now</latest>
</default>
</input>
<input type="dropdown" token="car_type_tok" searchWhenChanged="true">
<label>Car Type</label>
<choice value="ford">Ford</choice>
<choice value="chevy">Chevy</choice>
<choice value="honda">Honda</choice>
<choice value="toyota">Toyota</choice>
<choice value="tesla">Tesla</choice>
<change>
<set token="check_settings">true</set>
</change>
</input>
<input type="multiselect" token="car_model_tok" id="car_model_multiselect">
<label>Car Model</label>
<choice value="tahoe">Tahoe</choice>
<choice value="impala">Impala</choice>
<choice value="escape">Escape</choice>
<choice value="taurus">Taurus</choice>
<choice value="f150">F-150</choice>
<choice value="accord">Accord</choice>
<choice value="pilot">Pilot</choice>
<choice value="passport">Passport</choice>
<choice value="civic">Civic</choice>
<choice value="rav4">Rav4</choice>
<choice value="corolla">Corolla</choice>
<choice value="model3">Model3</choice>
<choice value="modelS">ModelS</choice>
<choice value="modelX">modelX</choice>
<delimiter> </delimiter>
</input>
<input type="text" token="car_color_tok">
<label>Car Color</label>
</input>
</fieldset>
</form>
Next, create the JavaScript file called 'input_settings.js' in the appserver/static folder of whatever app you're working in.
require(
[
'jquery',
'splunkjs/mvc'
],
function ($, mvc) {
// Create an instance of the save button
const save_config_button = $(`<button id="saveConfigButton" class="btn btn-primary">Save Configuration</button>`);
// Success message indicating config was saved
const success_message = $(`
<div id="successMessage" style="padding: 10px; background: #5cc05c; color: #FFFFFF; display: none">
Successfully saved the configuration!
</div>`);
// Instance of submitted tokens otherwise known as $form.tok$ in dashboard
const submitted_tokens = mvc.Components.get('submitted');
// Instance of the multiselect -- we need this to populate it from the KV store when we retrieve the settings
const car_model_multiselect = mvc.Components.get('car_model_multiselect');
// Instances of searches in our dashboard referenced by their ids
const save_dashboard_settings_search = mvc.Components.get('save_dashboard_settings_search');
const check_for_saved_settings_search = mvc.Components.get('check_for_saved_settings_search');
/*
* Get the results of a matching setting in the KV. This search is called on the dashboard init event
* as well as when the multi-valued field 'car_model_multiselect' is selected
*/
const check_for_saved_settings_results = check_for_saved_settings_search.data("results", {count: 0});
// Append the button to the dashboard
$('.dashboard-form-globalfieldset').append(save_config_button);
// Handle the click event on the save_config_button
save_config_button.on('click', function () {
// Disable it while the save action is occurring
save_config_button.prop('disabled', true);
// Change the text of the button to indicate its saving
save_config_button.text('Saving...');
/*
Sets the save_config token so that the 'save_dashboard_settings_search' runs -- this is
referenced in the depends of the 'save_dashboard_settings_search' e.g. depends="$save_config$"
*/
submitted_tokens.set({'save_config': true});
// Now run the search to save the settings
save_dashboard_settings_search.startSearch();
});
// Listen for the search to complete
save_dashboard_settings_search.on('search:done', function () {
// Re-enable the save button
save_config_button.prop('disabled', false);
// Change the text back to default
save_config_button.text('Save Configuration');
// Prepend the success message
$('.dashboard-form-globalfieldset').prepend(success_message);
// Success message hidden by default - fade it in over 1 second, show for 3 seconds, then fade out 1 sec.
success_message.fadeIn(1000).delay(3000).fadeOut(1000);
// Unset the 'save_config' token so the save config search doesn't unintentionally run
submitted_tokens.unset('save_config');
});
/*
* Wait for the check_for_saved_settings_results search to get data
*/
check_for_saved_settings_results.on("data", function () {
// Get the results of data
let rows = check_for_saved_settings_results.data().rows;
// Loops through the results
rows.forEach(function (row) {
// Turn result into an array
let car_models = row[0].split(' ');
// Populate the multi-select with the value of all the models
car_model_multiselect.val(car_models);
});
});
});
There is also a full demo app for this on Github here: https://github.com/deviansg/splunk_dashboard_input_settings in case you'd like to just have a working version to base everything off of.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Both solutions worked for me in the end - but this is a crazy amount of effort you put in to the answer so thanks for that, and exactly what I needed.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

@mwdbhyat do you have an idea of KV Store or do you want community to create the KV Store for this use case?
If you have already tried implementing KV Store and something is not working as expected please let us know.
I think as per your description instead of saving values Per Dashboard... Per User
, you want to do it Per Dashboard... Per 1st Input
value. This would mean in the KV Store the Key would be dashboard name + 1st input value
. If the same already exists in the KV Store you will update the other values otherwise you will insert.
Refer to Splunk Dev example for creation of KV Store (the same can also be done without HTML dashboard using Simple XML JS Extension and CSS Extension): http://dev.splunk.com/view/webframework-tutorials/SP-CAAAEZT
| makeresults | eval message= "Happy Splunking!!!"
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@niketn thanks for getting back to me! I have implemented a version with the HTML link above but the client would also like an option of not using HMTL, hence using the above method described..
I am using your dashboard as per my above mention in the dashboard and reconfigured it to do what I want(I just replaced the tokens and added a tail - | inputlookup "$env:app$_$env:user$".csv where tokLogLevel="$tokLogLevel$" |tail 1
| table tokTime_earliest tokTime_latest tokLogLevel )
So now if i select loglevel error with a 4h time range and hit save, it saves it so that if i then select something else and decide to come back to loglevel=error etc, it will recall the saved settings - job almost done.
The problem im facing now is that that save button JS seems to be stuck in an endless loop - so after I hit save it keeps "listening" and records everything i select on the dashboard to the lookup file. EG, it is not saving per click - its in a constant saving state until i refresh the page. Do you have any idea how i would stop that behaviour so that it only saves when I click on the save button?
Thanks!
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

@mwdbhyat if your solution worked fine with html dashboard in Splunk, you can use the same concept in Simple XML JS extension where you can invoke the REST API call to read/write or update KV Store on button click. (KV Store would be better that lookup file).
| makeresults | eval message= "Happy Splunking!!!"
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can use tokens between multiple input types so that when you select the first data type the next input results will auto populate on the previous token and so on you can pass the values. Let me know if it helps!
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

@manish_singh_777 I have converted your answer to comment, as I dont think it caters to the issue posted in the question.
| makeresults | eval message= "Happy Splunking!!!"
