TIPS & TRICKS TIPS & TRICKS

Making a dashboard with tabs (and searches that run when clicked)

In this post I am going to walk through how to make a dashboard with content separated into tabs. Not only will the content be divided into tabs, but the searches in the panels will not execute until the tabs are clicked. This prevents the dashboard from running all of the searches at once when the view is first opened.

Using tabs in this way serves two purposes:

  1. Prevent showing too much to a user all at once; a dashboard with more than 4 panels will require scrolling and may overwhelm the user
  2. Prevent too many searches from executing at once; this will improve load times, prevent time outs, and reduce load

The best way to walk through this tutorial is to download the sample app that I made and walk through each step. You can get the sample app here: tabs.tar.gz

Step 1: make your dashboard

The first step is to make your dashboard as you usually would. You can use Splunk’s UI to do this. Don’t worry about the tab logic yet, we will add that in later.

See the view titled “Step 1” in the tabs app to see the initial view.

So far, the view looks like this:

step1

 

This view has four panels, two of them are for the internal index and two are for non-internal indexes. I want to put the panels for internal and non-internal indexes in separate tabs.

Step 2: add the tab helper Javascript and CSS

I made some Javascript and CSS that will help you wire up the tabs. Go ahead and add it in. You can do this by copying the Javascript file “tabs.js” and “tabs.css” to the appserver/static directory of the app that has the view you want to add tabs to. For example, if the app is in the app “myapp”, then add the Javascript to “etc/apps/myapp/appserver/static/tabs.js” and the stylesheet to “etc/apps/myapp/appserver/static/tabs.css”. The files are available for download here:

Next, update your view to reference the css and js file. You can do this by declaring the script and stylesheet in the form or view tag. Here is an example:

<form script="tabs.js" stylesheet="tabs.css">

You will need to edit the source directly to make this change. Make sure to click “Edit source” in order to add this. You won’t notice any changes in your view yet even after you make the change. That’s ok, you will soon.

Step 3: declare your tabs

Now, lets add your tabs. You can do this by copying in a bit of HTML into your view. The tabs are going to be added in an html tag and the tabs themselves will be Bootstrap tabs (see the Bootstrap docs for details).

Put this just after your fieldset (or at the top if you have no fieldset tag). The top of my view now looks like this (changes in red):

<form script="tabs.js" stylesheet="tabs.css">
	<label>Tabs</label>
	<fieldset submitButton="true" autoRun="false">
	    <input type="time" token="field1" searchWhenChanged="false">
	      <label></label>
	      <default>
	        <earliest>-24h@h</earliest>
	        <latest>now</latest>
	      </default>
	    </input>
	</fieldset>
	<row id="tabs">
	   <panel>
	      <html>
	         <ul id="tabs" class="nav nav-tabs">
                    <li class="active">
                        <a href="#" class="toggle-tab" data-toggle="tab">Non-internal Indexes</a>
                    </li>
		    <li>
			<a href="#" class="toggle-tab" data-toggle="tab">Internal Index</a>
		    </li>
		 </ul>
	      </html>
	   </panel>
	</row>

This will make two Bootstrap tabs. The one named “Non-internal Indexes” is going to be the one that is shown by default since it has the “active” class associated with it.

Reload your view and you should find that you now have tabs! The tabs won’t do anything yet, we will wire them up next. The view should look something like this now:

step3

Step 4: wire up your tabs

Now, we will setup the tabs so that they show and hide the panels.

You will need to first set an id for each row that you want to be shown and hidden. To do this, just set the “id” to something that describes the tab. For example, I will name the first panel “tab_sourcetype” and the XML will look like this:

<row id="tab_sourcetype">

Do this for all of the panels that you want to be controlled by tabs. Then, create a “data-elements” attribute for each tab that indicates which rows to show and hide. The elements need to match exactly the id you set for each tab. Use a comma separated list if you have multiple rows that you want to be controlled by the tab. In my case, I have the following (note the “data-elements” attribute:

	<row id="tabs">
	   <panel>
	      <html>
	         <ul id="tabs" class="nav nav-tabs">
                    <li class="active">
                        <a href="#" class="toggle-tab" data-toggle="tab" data-elements="tab_source,tab_sourcetype">Non-internal Indexes</a>
                    </li>
		    <li>
		        <a href="#" class="toggle-tab" data-toggle="tab" data-elements="tab_source_internal,tab_sourcetype_internal">Internal Index</a>
		    </li>
		 </ul>
	      </html>
	    </panel>
	</row>

Once you reload the view, you should find that your tabs will show and hide the rows. The view will now look something like this:

step4

Step 5: wire up the tokens to prevent searches from running until the tab is clicked

This step is only required if you want to prevent the searches within the tabs from executing until the tab is clicked. To make this work, we are going to set some tokens that will only be defined when the tab is clicked. Splunk won’t try to run searches when the token isn’t defined and the tabs.js Javascript file won’t define the tokens until the tab is clicked. Thus, the searches won’t fire until the tab is clicked.

To make this work, first define a “data-token” attribute in each tab. Here are my tabs with the tokens defined:

	<row id="tabs">
	   <panel>
	      <html>
	         <ul id="tabs" class="nav nav-tabs">
                    <li class="active">
                        <a href="#" class="toggle-tab" data-toggle="tab" data-elements="tab_source,tab_sourcetype" data-token="control_token_non_internal">Non-internal Indexes</a>
                    </li>
		    <li>
			<a href="#" class="toggle-tab" data-toggle="tab" data-elements="tab_source_internal,tab_sourcetype_internal" data-token="control_token_internal">Internal Index</a>
		    </li>
		 </ul>
	      </html>
	   </panel>
	</row>

Next, add the the tokens to the searches. The name of the token should correspond to the tab that the search results will be available in. For example, I want the “Sourcetypes (internal)” and the “Source (internal)” panels to only execute when the “Internal Index” tab is clicked. Since the “Internal Index” tab has a token of “control_token_internal”, I’ll add that “control_token_internal” to the searches within that panel. Where you put the tokens doesn’t matter (the tokens are going to be removed when the searches run). You will need to surround them with dollar signs to denote them as tokens. In my case, the panels will look like this:

  <row id="tab_sourcetype_internal">
    <panel>
      <title>Sourcetypes (internal)</title>
      <table>
        <search>
          <query>| search * $control_token_internal$ index=_internal | stats count by sourcetype</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="count">10</option>
      </table>
    </panel>
  </row>
  
  <row id="tab_source_internal">
    <panel>
      <title>Source (internal)</title>
      <table>
        <search>
          <query>| search * $control_token_internal$ index=_internal | stats count by source</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="count">10</option>
      </table>
    </panel>
  </row>

Once you reload the view, you should find that the tokens for the panels will not execute until you click the tabs.

Wrapping up

I made a sample app that illustrates each step. Feel free to download the app and play around with it. Get the file here: tabs.tar.gz

Luke Murphey
Posted by Luke Murphey

Join the Discussion