How to create a custom table row renderer using SplunkJS Stack

By creating a custom row renderer, you can provide a detailed view of a table row when it is expanded. Only one row can be expanded at a time in each table. Your custom row renderer defines when to display a details view, what data to display, and the format. You can add one or more custom row renderers to a table, with the last renderer added taking priority.

Here's an example of a custom renderer that displays a chart in the expanded row detail:

[Table with a custom row expansion renderer]

To create a custom row renderer, write a class that inherits from the Table view's BaseRowExpansionRenderer class, which has the following methods that you can override:

  • initialize: function(): Initializes setup.
  • canRender: function(rowData): Required. Indicates when to apply custom row rendering. When this method returns true, the custom row renderer is applied to display a details view.
  • createContainer: function(rowData): Returns the container for the details view of the expanded row. By default, the base class returns a jQuery object that creates one cell with a colspan that includes all columns:
  • return $: function('<td colspan="' + rowData.colspan + '"></td>');

    To use a different layout, return a custom jQuery object.

  • setup: function($container, rowData): Runs each time a row is expanded, before rendering the row.
  • render: function($container, rowData): Required. Renders the expanded row's details view.
  • teardown: function($container, rowData): Runs when a row is collapsed and can be used to clear resources.

The function parameters contain the following information:

  • $container: Contains the jQuery element that was created with the createContainer method.
  • rowData: Contains data about the row that is selected. The rowData object contains the following fields:
    • cells: The array of information about the cells in the current row.
    • colspan: The number of columns.
    • fields: The array of row fields.
    • rowIndex: The index of the current row.
    • table: The parent table.
    • values: The array of row values.

The following example shows the basic structure for creating a custom row renderer:

// Require the Table view library
require([
    "splunkjs/mvc/tableview",
    "splunkjs/mvc/simplexml/ready!"
], function(TableView) {

    // Inherit from the BaseRowExpansionRenderer base class
    var MyCustomRowRenderer = TableView.BaseRowExpansionRenderer.extend({
        initialize: function() {
            ...
        },
        canRender: function(rowData) {
            // Required
            ...
        },
        createContainer: function(rowData) {
            ...
        },
        setup: function($container, rowData) {
            ...
        },
        teardown: function($container, rowData) {
            ...
        },
        render: function($container, rowData) {
            // Required
            ...
        }
    });

   ...
   
});

To work with your custom row renderer, use these methods with the Table view:

  • addRowExpansionRenderer(renderer): Adds a row renderer to the table, where renderer is an instance of your custom row renderer.
  • removeRowExpansionRenderer(renderer): Removes a row renderer from the table, where renderer is an instance of your custom row renderer.
  • getRowExpansionRenderers: Gets an array of the row renderers that have been added to the table.
  • expandRow(index): Expands the row specified by index, and collapses the currently-expanded row.
  • collapseRow: Collapses the currently-expanded row.
  • render: Draws the view to the screen.

The following example shows how to create a very basic row renderer that simply displays values from the rowData object for the selected row. Only two methods are overridden: canRender, which is required, and render.

        <h3>Example: A master-detail view, BASIC</h3>
        <div id="mytable"></div>

 

    require([
        "underscore",
        "splunkjs/mvc/searchmanager",
        "splunkjs/mvc/tableview",
        "splunkjs/mvc/simplexml/ready!"
    ], function(
       _,
       SearchManager,
       TableView
    ) {

    // Create a search manager
    var mysearch = new SearchManager({
        id: "main-search",
        preview: true,
        cache: true,
        search: "index=_internal | stats count by sourcetype, source, host"
    });

    // Create a table
    var myTableView = new TableView({
        id: "mytable",
        managerid: "main-search",
        drilldown: "none",
        el: $("#mytable")
    });

    // Create a basic custom row renderer
    var BasicRowRenderer = 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 basic row renderer
    var tableRowRender = new BasicRowRenderer();

    // Add the row renderer to the table
    myTableView.addRowExpansionRenderer(tableRowRender);

    // Render the table
    myTableView.render();
});