Developing for Splunk Enterprise

How to create custom row expansion in a table?

astatrial
Communicator

Hello guys !
I'm trying to create a custom row expansion, which seemed to be simple task and became a big headache.
Before i even will try to add a meaningful data, i am just trying to add generic data to the rows.

This is my JS :

require([
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/chartview',
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc',
    'underscore',
    'splunkjs/mvc/simplexml/ready!'],function(
    TableView,
    ChartView,
    SearchManager,
    mvc,
    _
    ){
    // Create a search manager
    var mysearch = new SearchManager({
        id: "main-search",
        preview: false,
        cache: false,
        search: "| makeresults | eval check=3 | fields - _time"
    });

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

    //create row renderer
    var EventSearchBasedRowExpansionRenderer = 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);
            $container.append(mysearch);
        }
    });

    // Create an instance of the basic row renderer
    var tableRowRender = new EventSearchBasedRowExpansionRenderer();

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

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

In addition i added to the source of the dashboard the script="custom_table_row_expansion.js" and the table id="myTableView".

Can anyone help me with that ?

Thanks.

alt text

Labels (1)
0 Karma
1 Solution

vnravikumar
Champion

Hi @astatrial

Try this sample

<form script="custom.js">
  <label>custom_row</label>
  <fieldset submitButton="false">
    <input type="time" token="timepicker">
      <label></label>
      <default>
        <earliest></earliest>
        <latest></latest>
      </default>
    </input>
  </fieldset>
  <row>
    <panel>
      <table id="expand_table_row">
        <search>
          <query>index=_* type="threat" severity="medium" | table host source sourcetype search_id</query>
          <earliest>$timepicker.earliest$</earliest>
          <latest>$timepicker.latest$</latest>
        </search>
        <option name="drilldown">none</option>
      </table>
    </panel>
  </row>
</form>

custom.js

require([
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/eventsviewerview',
    "splunkjs/mvc/chartview",
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc',
    'underscore',
    'splunkjs/mvc/simplexml/ready!'
],function(
    TableView,
    EventsViewer,
    ChartView,
    SearchManager,
    mvc,
    _
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
    initialize: function(args) {
        // initialize will run once, so we will set up a search and events to be reused.
        this._searchManager = new SearchManager({
            id: 'details-search-manager',
            preview: false
        });
        this.chartViewer = new ChartView({
            type: "bar",
            managerid: 'details-search-manager'
        });
    },
    canRender: function(rowData) {
        // Since more than one row expansion renderer can be registered we let each decide if
        // they can handle that data
        // Here we will always handle it.
        return true;
    },
    render: function($container, rowData) {
        // rowData contains information about the row that is expanded.  We can see the cells, fields, and values
        // We will find the sourcetype cell to use its value
        var search_idCell = _(rowData.cells).find(function (cell) {
           return cell.field === 'search_id';
        });
        console.log(search_idCell);
        //update the search with the sourcetype that we are interested in
        this._searchManager.set({
            earliest_time: "$form.timepicker.earliest$",
            latest_time: "$form.timepicker.latest$",
            search: 'index=_* type="threat" severity="medium" search_id=' + search_idCell.value +' | stats count by host'
        }, {tokens: true});
        // $container is the jquery object where we can put out content.
        // In this case we will render our chart and add it to the $container
        $container.append(this.chartViewer.render().el);
    }
});
var tableElement = mvc.Components.getInstance("expand_table_row");
tableElement.getVisualization(function(tableView) {
    // Add custom cell renderer, the table will re-render automatically.
    tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});

});

alt text

View solution in original post

iamkilarunaresh
Explorer

Hello @vnravikumar I have a similar question, Please let me know if we can do it with HTML or CSS? We are Splunk cloud so it is bit hard for us with javascript.  

0 Karma

thambisetty
Super Champion

you can  not do it without using JS.

————————————
If this helps, give a like below.
0 Karma

vnravikumar
Champion

Hi @astatrial

Try this sample

<form script="custom.js">
  <label>custom_row</label>
  <fieldset submitButton="false">
    <input type="time" token="timepicker">
      <label></label>
      <default>
        <earliest></earliest>
        <latest></latest>
      </default>
    </input>
  </fieldset>
  <row>
    <panel>
      <table id="expand_table_row">
        <search>
          <query>index=_* type="threat" severity="medium" | table host source sourcetype search_id</query>
          <earliest>$timepicker.earliest$</earliest>
          <latest>$timepicker.latest$</latest>
        </search>
        <option name="drilldown">none</option>
      </table>
    </panel>
  </row>
</form>

custom.js

require([
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/eventsviewerview',
    "splunkjs/mvc/chartview",
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc',
    'underscore',
    'splunkjs/mvc/simplexml/ready!'
],function(
    TableView,
    EventsViewer,
    ChartView,
    SearchManager,
    mvc,
    _
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
    initialize: function(args) {
        // initialize will run once, so we will set up a search and events to be reused.
        this._searchManager = new SearchManager({
            id: 'details-search-manager',
            preview: false
        });
        this.chartViewer = new ChartView({
            type: "bar",
            managerid: 'details-search-manager'
        });
    },
    canRender: function(rowData) {
        // Since more than one row expansion renderer can be registered we let each decide if
        // they can handle that data
        // Here we will always handle it.
        return true;
    },
    render: function($container, rowData) {
        // rowData contains information about the row that is expanded.  We can see the cells, fields, and values
        // We will find the sourcetype cell to use its value
        var search_idCell = _(rowData.cells).find(function (cell) {
           return cell.field === 'search_id';
        });
        console.log(search_idCell);
        //update the search with the sourcetype that we are interested in
        this._searchManager.set({
            earliest_time: "$form.timepicker.earliest$",
            latest_time: "$form.timepicker.latest$",
            search: 'index=_* type="threat" severity="medium" search_id=' + search_idCell.value +' | stats count by host'
        }, {tokens: true});
        // $container is the jquery object where we can put out content.
        // In this case we will render our chart and add it to the $container
        $container.append(this.chartViewer.render().el);
    }
});
var tableElement = mvc.Components.getInstance("expand_table_row");
tableElement.getVisualization(function(tableView) {
    // Add custom cell renderer, the table will re-render automatically.
    tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});

});

alt text

View solution in original post

astatrial
Communicator

I don't want a chart, i just want a table.
I came across this example already.

0 Karma

vnravikumar
Champion

Hi @astatrial

Try this javascript it will render a table and please let me know your requirement clearly

  require([
        'splunkjs/mvc/tableview',
        'splunkjs/mvc/eventsviewerview',
        "splunkjs/mvc/chartview",
        'splunkjs/mvc/searchmanager',
        'splunkjs/mvc',
        'underscore',
        'splunkjs/mvc/simplexml/ready!'
    ],function(
        TableView,
        EventsViewer,
        ChartView,
        SearchManager,
        mvc,
        _
    ){
    var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
        initialize: function(args) {
            // initialize will run once, so we will set up a search and events to be reused.
            this._searchManager = new SearchManager({
                id: 'details-search-manager',
                preview: false
            });
            this.tableViewer = new TableView({
                pageSize: "5",
                id: "example-table",
                managerid: 'details-search-manager'
            });
        },
        canRender: function(rowData) {
            // Since more than one row expansion renderer can be registered we let each decide if
            // they can handle that data
            // Here we will always handle it.
            return true;
        },
        render: function($container, rowData) {
            // rowData contains information about the row that is expanded.  We can see the cells, fields, and values
            // We will find the sourcetype cell to use its value
            var search_idCell = _(rowData.cells).find(function (cell) {
               return cell.field === 'search_id';
            });
            console.log(search_idCell);
            //update the search with the sourcetype that we are interested in
            this._searchManager.set({
                earliest_time: "$form.timepicker.earliest$",
                latest_time: "$form.timepicker.latest$",
                search: 'index=_* type="threat" severity="medium" search_id=' + search_idCell.value +' | stats count by host'
            }, {tokens: true});
            // $container is the jquery object where we can put out content.
            // In this case we will render our chart and add it to the $container
            $container.append(this.tableViewer.render().el);
        }
    });
    var tableElement = mvc.Components.getInstance("expand_table_row");
    tableElement.getVisualization(function(tableView) {
        // Add custom cell renderer, the table will re-render automatically.
        tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
    });

    });
0 Karma

hrs2019
Path Finder

@vnravikumar   can we use the same custom row expansion logic using  XML /HTML/CSS.
Since I don't have access to upload JS file in Splunk so looking for same solution in  XML/HTML/CSS?

0 Karma

astatrial
Communicator

Hi,
sorry if my question wasn't clear.
I have a dashborad and i am trying to add data to every row in a table format.
I have a base search and the panel that i want to add to the row expansion is using it.

I added the JS to the /appserver/static folder and modified the dashboard source code to add the script and the "expand_table_row".

I also tried to just create a new dashboard with the code you wrote and the add the JS, but it also didn't work .

I restarted the splunk and cleared the browser data, but i don't see any change in the dashboard (it doesn't even show the small arrow to the left of the row).

I don't know why and i can't even find a way to debug it.

When i

0 Karma

vnravikumar
Champion

Hi @astatrial

Can you inspect with your browser and check whether you are getting any javascript error. And also let me know whether you are expecting the result as like below.

alt text

0 Karma

astatrial
Communicator

This is exactly what i am trying to do(!), with no success.
I don't see any javascript errors

I added a print screen of the browser inspection .

0 Karma

vnravikumar
Champion

Whether javascript get invoked?

0 Karma

astatrial
Communicator

"Whether javascript get invoked?"
I am not sure what are you meaning here?
The splunk version is - 7.2.4.2

Also if it is not obvious i really appreciate your help!!

0 Karma

vnravikumar
Champion

I also tried in same Splunk version. Let me know whether the javascript file that you included in the dashboard, getting called. Try to put some log statement in javascript file like console.log("Testing Javascript file -----"); I guess Javascript file not called properly.

0 Karma

astatrial
Communicator

This was exactly the problem..
I edited the JS file in a wrong way and it prevented it from being called.

By the way, do you know if there is an option to add button to the row expansion
(I just want to know if you think this thing is optional or not).

Thanks for everything !

0 Karma

vnravikumar
Champion

Instead of a small triangle image do you need to add button there? If that is the case you need to handle in css.

0 Karma

astatrial
Communicator

Thanks for the response.
No, my question is if it possible that row expansion will be opened to an interactive board from which i will be able to modify things like edit lookup fields.

0 Karma

vnravikumar
Champion

And also let me know your Splunk version

0 Karma
.conf21 CFS Extended through 5/20!

Don't miss your chance
to share your Splunk
wisdom in-person or
virtually at .conf21!

Call for Speakers has
been extended through
Thursday, 5/20!