Example: Tables with custom renderers using JavaScript for apps outside Splunk Web

This example uses JavaScript to display a table that includes a sparkline in the search results, a second version of the table shows how to format the sparkline and create a custom cell renderer, and a third table that uses a custom row expansion renderer.

To use this code, save it as an HTML file in your own web site's directory. Be sure to update the splunkjs.config section for your own web app. The authenticate function redirects to a login_form.html example login page, which you can find here. For more, see Use SplunkJS Stack in your own web apps.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Custom Table Renderers</title>

    <link rel="stylesheet" type="text/css" href="static/splunkjs/css/bootstrap.css" />
    <link rel="stylesheet" type="text/css" href="static/splunkjs/css/dashboard.css" />

    <!-- Define icon styles -->
    <style>
        td.icon {
            text-align: center;
        }
        td.icon i {
            font-size: 15px;
            text-shadow: 1px 1px #aaa;
        }
        td.icon .severe {
            color: red;
        }
        td.icon .elevated {
            color: orangered;
        }
        td.icon .low {
            color: #006400;
        }
    </style>
</head>

<body>
    <div class="dashboard-body container-fluid main-section-body">

        <div class="row">
            <div class="dashboard-header clearfix">
                <h2>Custom cell and row renderers</h2>
            </div>
        </div>

        <div class="dashboard-row">
            <div class="dashboard-cell" style="width: 100%;">
                <div class="dashboard-panel">
                    <div class="panel-head">
                        <h3>Standard table cells</h3>
                    </div>
                    <div class="panel-body">
                        <div id="table-plain"></div>
                    </div>
                </div>
            </div>
        </div>

        <div class="dashboard-row">
            <div class="dashboard-cell" style="width: 100%;">
                <div class="dashboard-panel">
                    <div class="panel-head">
                        <h3>Custom table cells</h3>
                    </div>
                    <div class="panel-body">
                        <div id="table-customcell"></div>
                    </div>
                </div>
            </div>
        </div>

        <div class="dashboard-row">
            <div class="dashboard-cell" style="width: 100%;">
                <div class="dashboard-panel">
                    <div class="panel-head">
                        <h3>Custom expanding table rows</h3>
                    </div>
                    <div class="panel-body">
                        <div id="table-customrow"></div>
                    </div>
                </div>
            </div>
        </div>

    </div>

    <script src="static/splunkjs/config.js"></script>

    <script>
        // Configure SplunkJS Stack
        splunkjs.config({
            proxyPath: "/proxy",
            scheme: "https",
            host: "localhost",
            port: 8089,
            authenticate: function(done) { 
                require([
                    "jquery",
                    "jquery.cookie"
                ], function($) {
                    // Retrieve the session key and username from cookies
                    var splunkSessionKey = $.cookie("splunk_sessionkey");
                    var splunkCurrentUser = $.cookie("splunk_username");

                    // Log in using the session key and username
                    if (splunkSessionKey) {
                        done(null, {sessionKey: splunkSessionKey, username: splunkCurrentUser}); 
                    }
                    // If there is no session key, redirect to the login form
                    else {
                        window.location.replace("login_form.html");
                    }
                });
            }
        });
        
        // Configure the web site's base URL
        require.config({
            baseUrl: "static/"
        });

        // Set up the Web Framework components
        var deps = [
            "splunkjs/ready!",
            "underscore",
            "splunkjs/mvc/searchmanager",
            "splunkjs/mvc/tableview"
        ];
        require(deps, function(mvc,_) {
            // Load individual components
            var SearchManager = require("splunkjs/mvc/searchmanager");
            var TableView = require("splunkjs/mvc/tableview");

            // Set up search managers
            var search1 = new SearchManager({
                id: "search1",
                search: "index=_internal | head 10000 | stats sparkline count by sourcetype | rangemap field=count low=0-100 elevated=101-1000 default=severe",
                earliest_time: "-1h@h", 
                latest_time: "now",
                preview: true,
                cache: true
            });

            var search2 = new SearchManager({
                id: "search2",
                preview: true,
                cache: true,
                search: "index=_internal | stats count by sourcetype, source, host" 
            });

            // Create a table
            var myplaintable = new TableView({
                id: "table-plain",
                managerid: "search1",
                el: $("#table-plain")
            }).render();

            // Create a custom table and set sparkline properties
            var mycustomcelltable = new TableView({
                id: "table-customcell",
                managerid: "search1",
                el: $("#table-customcell"),
                // Format the sparkline cell
                format: {
                    "sparkline": [ // This field name is required
                        {
                            "type": "sparkline", // This property must be "sparkline"

                            // Sparkline options
                            "options": 
                            {
                                "type": "bar",
                                "height": "40px", 
                                "barWidth": "5px",
                                "colorMap": 
                                {
                                    "100:": "#0033CC", 
                                    ":99": "#00FF00"
                                }
                            }
                        }
                    ]
                }
            });

            // Create a table for a custom row expander
            var mycustomrowtable = new TableView({
                id: "table-customrow",
                managerid: "search2",
                drilldown: "none",
                el: $("#table-customrow")
            });

            // Define icons for the custom table cell
            var ICONS = {
                severe: "alert-circle",
                elevated: "alert",
                low: "check-circle"
            };

            // Use the BaseCellRenderer class to create a custom table cell renderer
            var CustomCellRenderer = TableView.BaseCellRenderer.extend({ 
                canRender: function(cellData) {
                    // This method returns "true" for the "range" field
                    return cellData.field === "range";
                },

                // This render function only works when canRender returns "true"
                render: function($td, cellData) {
                    console.log("cellData: ", cellData);

                    var icon = "question";
                    if(ICONS.hasOwnProperty(cellData.value)) {
                        icon = ICONS[cellData.value];
                    }
                    $td.addClass("icon").html(_.template('<i class="icon-<%-icon%> <%- range %>" title="<%- range %>"></i>', {
                        icon: icon,
                        range: cellData.value
                    }));
                }
            });

            // Use the BasicRowRenderer class to create a custom table row renderer
            var CustomRowRenderer = TableView.BaseRowExpansionRenderer.extend({
                canRender: function(rowData) {
                    console.log("RowData: ", rowData); 
                    return true;
                },

                render: function($container, rowData) {
                // Print the rowData object to the console
                console.log("RowData: ", rowData); 

                // Display some of the rowData in the expanded row
                $container.append("<div>" 
                    + "<b>rowIndex</b>: " + rowData.rowIndex + "<br>" 
                    + "<b>colspan</b>: " + rowData.colspan + "<br>" 
                    + "<b>fields</b>: " + rowData.fields + "<br>" 
                    + "<b>values</b>: " + rowData.values
                    + "</div>");
                }
            });

            // Create an instance of the custom cell renderer,
            // add it to the table, and render the table
            var myCellRenderer = new CustomCellRenderer(); 
            mycustomcelltable.addCellRenderer(myCellRenderer);  
            mycustomcelltable.render();

            // Create an instance of the custom row renderer,
            // add it to the table, and render the table
            var myRowRenderer = new CustomRowRenderer(); 
            mycustomrowtable.addRowExpansionRenderer(myRowRenderer); 
            mycustomrowtable.render();

        });
    </script>
</body>
</html>