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.
... View more