Transform and validate tokens

For various reasons, using a simple token variable might not be enough. You might need to manipulate the value of a token directly or by using a custom function. You might need to validate token values before using them. Or, you might need to generate a token from one or more input tokens. This section shows you different ways to work with tokens.

Create a token change event handler

You can create a change event handler that is triggered when a token value changes by using the following format:

// Retrieve the default token model
var defaultTokenModel = mvc.Components.get("default");

// Listen for a change to the token value
defaultTokenModel.on("change:tokenName", function(model, value, options) {
    ...
});

The following example displays a list of indexes to search. One of the dropdown choices is not a valid index name, but allows the user to request results from multiple indexes. The change event handler is triggered when a selection is made, then forms a search query based on the selection.

<script>
    require([
        "splunkjs/mvc",
        "splunkjs/mvc/searchmanager",
        "splunkjs/mvc/dropdownview",
        "splunkjs/mvc/tableview",
        "splunkjs/mvc/simplexml/ready!"
        ], function(
            mvc,
            SearchManager,
            DropdownView,
            TableView
        ) {

        // Search query is based on the selected index
        var indexsearch = new SearchManager({
            id: "indexsearch",
            cache: true,
            search: mvc.tokenSafe("$searchQuery$")
        });

        // Display an arbitrary list of indexes
        var indexlist = new DropdownView({
            id:"indexlist",
            choices: [
                {label: "main", value: "main"},
                {label: "_internal", value: "_internal"},
                {label: "_audit", value: "_audit"},
                {label: "<all>", value: "all"} // Not a valid index name
            ],
            showClearButton: false,
            value: mvc.tokenSafe("$indexName$"),
            el: $("#indexlist")
        }).render();

        // When the $indexName$ token changes, form the search query
        var defaultTokenModel = mvc.Components.get("default");
        defaultTokenModel.on("change:indexName", function(newIndexName, indexName, options) {
            var newQuery = " | stats count by sourcetype, index";
            if (indexName == "all") {
                newQuery = "index=_internal OR index=_audit OR index=main" + newQuery;
            } else {
                newQuery = "index=" + indexName + newQuery;
            }
            // Update the $searchQuery$ token value
            defaultTokenModel.set("searchQuery", newQuery);
        });

        // Display the search results
        var tableindex = new TableView({
            id: "tableindex",
            managerid: "indexsearch",
            pageSize: 5,
            el: $("#tableindex")
        }).render();

    });
</script>

Create a filter to transform a token value

To transform a single token value, you can create a filter that takes a token and returns a value, without affecting the original token. Create a filter using the following format:

mvc.setFilter("filterName", function(inputValue) {
    ...
    return transformedValue;
});

To use the filter, use this syntax:

mvc.tokenSafe("$inputToken|filterName$")

The following example displays a list of fields to search. Depending on the selected field, a search query is formed, the search is run, and results are displayed. For this example, the filter takes the selected field as an input token, and returns a value for the search query based on the selected field.

<script>
    require([
        "splunkjs/mvc",
        "splunkjs/mvc/searchmanager",
        "splunkjs/mvc/dropdownview",
        "splunkjs/mvc/tableview",
        "splunkjs/mvc/simplexml/ready!"
        ], function(
            mvc,
            SearchManager,
            DropdownView,
            TableView
        ) {

        // Display a list of fields choices for searching
        var fieldChoices = new DropdownView({
            id: "fieldChoices",
            choices: [
                {label: "host", value: "host"},
                {label: "sourcetype", value: "sourcetype"},
                {label: "source", value: "source"},
                {label: "status", value: "status"},
                {label: "message", value: "message"} // Only valid when index=_internal
            ],
            default: "host",
            showClearButton: false,
            value: mvc.tokenSafe("$selectedField$"),
            el: $("#fieldChoices")
        }).render();

        // Create a search manager that transforms a token
        var mysearch = new SearchManager({
            id: "mysearch",
            cache: true,
            search: mvc.tokenSafe("$selectedField|makeSearchQuery$")
        });

        // Transform $selectedField$ and return a value. $selectedField$ is not affected.
        mvc.setFilter("makeSearchQuery", function(selectedField) {
            var searchQuery = (selectedField==="message")
                ? "index=_internal | top 3 message"
                : "* | top 3 " + selectedField;
            return searchQuery;
        });

        // Display the results
        var mytable = new TableView({
            id: "mytable",
            managerid: "mysearch",
            el: $("#mytable")
        }).render();

    });
</script>

Create a token forwarder

Another way to work with tokens is by using a token forwarder to transform one or more input tokens into a new output token. You can also use a token forwarder to validate input tokens, and take special action for invalid input. If the token forwarder returns TokenForwarder.NO_CHANGE, the output token value will not be changed.

Create a token forwarder using the tokenforwarder class in the following format:

// Require the tokenforwarder class
require([
    "splunkjs/mvc",
    "splunkjs/mvc/tokenforwarder",
    "splunkjs/mvc/simplexml/ready!"
    ], function(mvc, TokenForwarder) {
    var myForwarder = new TokenForwarder(
        ["$inputToken1$", ..., "$inputTokenN"],
        "$outputToken$",
        function(inputTokenVal1, ..., inputTokenValN) {
            ...
            return outputTokenValue;
        }
    );
});

To use the token forwarder, use this syntax:

mvc.tokenSafe("$outputToken$")

For more, see TokenForwarder in the Splunk Web Framework Component Reference.

The following example displays a list of fields to search. Depending on the selected field, a search query is formed, the search is run, and results are displayed. For this example, the filter takes the selected field as a single input token, and a search query based on the selected field is returned in the output token.

<script>
require([
        "splunkjs/mvc",
        "splunkjs/mvc/searchmanager",
        "splunkjs/mvc/dropdownview",
        "splunkjs/mvc/tableview",
        "splunkjs/mvc/tokenforwarder",
        "splunkjs/mvc/simplexml/ready!"
    ], function(
        mvc,
        SearchManager,
        DropdownView,
        TableView,
        TokenForwarder
    ) {

        // Display a list of fields choices for searching
        var fieldChoices = new DropdownView({
            id: "fieldChoices",
            choices: [
                {label: "host", value: "host"},
                {label: "sourcetype", value: "sourcetype"},
                {label: "source", value: "source"},
                {label: "status", value: "status"},
                {label: "message", value: "message"} // Only valid when index=_internal
            ],
            default: "host",
            showClearButton: false,
            value: mvc.tokenSafe("$selectedField$"),
            el: $("#fieldChoices")
        }).render();

        // Create a search manager that uses token forwarding
        var mysearch = new SearchManager({
            id: "mysearch",
            cache: true,
            search: mvc.tokenSafe("$searchQuery$")
        });

        // Form a new token $searchQuery$ from $selectedField$
        new TokenForwarder("$selectedField$", "$searchQuery$", function(selectedField) {
            var searchQuery = (selectedField === "message")
                ? "index=_internal | top 3 message"
                : "* | top 3 " + selectedField;
            return searchQuery;
        });

        // Display the results for each method
        var mytable = new TableView({
            id: "mytable",
            managerid: "mysearch",
            el: $("#mytable")
        }).render();

    });
</script>