Reusable UI Components in Splunk: A Search Help Menu [Part 3]

This tutorial goes over the build-out process of creating a custom, reusable search help menu in Splunk. This helps the user as it provides additional context.



Part 3: Define a JavaScript Module

Everything works as expected, but we can still clean up our code and move our MenuLinkView view into a separate file. This will make our index.js file smaller and will separate out our components. While this isn’t absolutely necessary for a project of this size, it's something that should be considered, especially if you end up building something on a much larger scale.

First thing, inside of your app’s appserver/static folder, create a new folder called ‘components’. Then go into your components folder and add a new file called 'MenuLinkView.js'.

Open up MenuLinkView.js and add the following:

define([
    'underscore',
    'backbone',
    'splunkjs/mvc',
    'views/shared/delegates/Popdown'
], function(_, Backbone, mvc, Popdown){

});

Here we are going to define our MenuLinkView as a module that we can easily import into our index.js file and create a new instance of. The difference here is that we are using define() instead of require(), which we are using inside of index.js. Why define()? It allows us to set up a reusable module using require.js, which is the library that Splunk uses to load in all of JS dependencies.

Next, inside of the define function, add your template and MenuLinkView:

var linkPopDownTpl = '<a href="#" class="popdown-toggle viewMore"><%-linkText %></a>' +
                     '<div class="dropdown-menu pivot-dropdown">' +
                     '<div class="arrow" style="margin-left: -8px;"></div>' +
                     '<div class="slideNavPlaceHolder help-text">' +
                     '<div class="auto">' +
                     '<p class="popdown-body"><%-text %></p>'
                     '</div></div></div>';

var MenuLinkView = Backbone.View.extend({
    initialize: function(attrs) {
        this.text = attrs['text'];
        this.linkText = attrs['link-text']
    },
    tagName: 'span',
    render: function() {
        this.$el.html(_.template(linkPopDownTpl, {
            linkText: this.linkText,
            text: this.text
        }));
        this.popdown = new Popdown({
            el:this.$el,
            dialog: '.pivot-dropdown',
            attachDialogTo: 'body',
            mode: 'dialog'});
    }
});

And finally, below the MenuLinkView add:

return MenuLInkView;

Back in index.js we need to make some changes. First, remove the reference to loading in the Popdown component, as this is now being loaded in in the MenuLinkView.js file. Next, we need to add a reference to the MenuLinkView file by adding this: 

'../app/help_menu/components/MenuLinkView',

Then add MenuLinkView as a function parameter:

require([
    'underscore',
    'backbone',
    'jquery',
    'splunkjs/mvc',
    '../app/help_menu/components/MenuLinkView',
    'splunkjs/mvc/simplexml/ready!'
], function(_, Backbone,$, mvc, MenuLinkView) {

Next, you can remove both the template (linkPopDownTpl) and the original MenuLinkView. Your index.js file should now look like this:

require([
    'underscore',
    'backbone',
    'jquery',
    'splunkjs/mvc',
    '../app/help_menu/components/MenuLinkView',
    'splunkjs/mvc/simplexml/ready!'
], function(_, Backbone,$, mvc, MenuLinkView) {

    $('.help-button').each(function() {

        var helpButtonContainer = $(this);

        var helpMenuLink = new MenuLinkView({ "link-text": helpButtonContainer.data('link-text'),
 "text": helpButtonContainer.data('text') });
        helpButtonContainer.append(helpMenuLink.$el);
        helpMenuLink.render();

    });

});

Now, save your index.js file and refresh the dashboard. Everything should be working as before, except now it is separated out to make our code cleaner.

Adding Some Style

Inside of your Help Menu app’s appserver/static directory, create a new file called popdown_menu.css, and add the following:

.help-button {
	background-color: #222;
	display: inline;
	-webkit-border-radius: 12px;
	-moz-border-radius: 12px;
	border-radius: 12px;
}
.help-button span a {
	color: white;
	text-decoration: none;
	padding: 4px;
}
.popdown-body {
	background: white;
	padding: 6px;
}
.help-text p {
	margin: 0;
}

This is styling the '?' so it will be wrapped in a black circle to make it look more like a button. We are also adding some padding and background color of white to the popdown-body to give the text some breathing room.

Once you add this to the stylesheet, restart Splunk $SPLUNK_HOME/bin/splunk restart

When the restart completes, go back to your dashboard and edit the source ‘Edit’ < ‘Edit source’ and a reference to the new stylesheet:

Save your change and then on the dashboard the style change should take affect:

That looks better -- and that's it.

Also, because we are done developing, you can remove or change the js_no_cache setting to false in our local web.conf found in $SPLUNK_HOME/etc/system/local/:

[settings]
js_no_cache = True

At this point we have created a reusable component that we can attach to multiple panels on a dashboard, and across as many dashboards as we want. Its also very easy to set up new instances of the popdown menu. Again, not only can this be reused, but it has the additional value of providing your user with additional context.

If you need to reference the other tutorial parts, you will find links below:

Part 1 Part 2

And, of course, for the completed version visit HurricaneLabs GitHub.




Close off Canvas Menu