- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Table under table row expasion automatically inherits drilldown from parent table
Hi there!
I have a use case where I need to put a table under a Table row expansion and I need to have the ability to drilldown from both tables (parent & child). My XML + JS code works Ok, but I'm realizing that my child table somehow inherits the drilldown settings from the parent table. I was able to reproduce my issue using the Table Row Expansion code from the Splunk Examples App.
This is how my table looks like
Let's say that when you click on "mongod" I would like open a link to google.com while if you click on a value under "_raw" I would like to open a link to yahoo.com. Here's my run anywhere code
<dashboard script="custom_table_row_expansion.js">
<label>Table Row Expansion</label>
<description>Show more information on click of expansion.</description>
<row>
<panel>
<table id="expand_with_events">
<search>
<query>index=_internal | stats count by sourcetype</query>
<earliest>-24h</earliest>
<latest>now</latest>
</search>
<option name="drilldown">cell</option>
<option name="percentagesRow">false</option>
<option name="totalsRow">false</option>
<drilldown>
<condition field="sourcetype">
<link target="_blank">https://www.google.com</link>
</condition>
</drilldown>
</table>
</panel>
</row>
</dashboard>
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/chartview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'],function(
TableView,
ChartView,
SearchManager,
mvc,
_
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
this._searchManager = new SearchManager({
id: 'details-search-manager',
preview: false
});
this._TableView = new TableView({
id: 'TestTable',
managerid: 'details-search-manager',
drilldown: 'cell'
});
},
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 sourcetypeCell = _(rowData.cells).find(function (cell) {
return cell.field === 'sourcetype';
});
//update the search with the sourcetype that we are interested in
this._searchManager.set({ search: 'index=_internal sourcetype=' + sourcetypeCell.value + ''});
// $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._TableView.render().el);
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
tableclick = splunkjs.mvc.Components.get("TestTable");
tableclick.on("click", function (e) {
e.preventDefault(); // Prevent redirecting to the Search app
window.open('www.yahoo.com','_blank');
});
});
So here's what happens ... if I click on a value under "sourcetype" the drilldown works fine and it takes me to google.com, but if I click on a value under "_raw" it automatically opens two tab on google.com + 1 tab on yahoo.com (See example below, don't worry about the page not found error)
If I switch the child object from Table to a Pie chart everything works fine , so the issue seems to be related to a child table under a Table Row Expansion situation.
Is this a bug? a design thing? what am I missing here? BTW I tested this on 7.2.1 and 8.x and got the same issue.
TIA!
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think my workaround would be create a new dashboard for all the Child data and then iframe the child data.
Here's the XML for the new Child data
Table Row Expansion Child
<input type="text" token="prmSourceType">
<label>SourceType</label>
</input>
<panel>
<table>
<search>
<query>index=_internal sourcetype=$prmSourceType|s$ | table _raw</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
</search>
<option name="drilldown">cell</option>
<option name="refresh.display">progressbar</option>
<drilldown>
<link target="_blank">www.yahoo.com</link>
</drilldown>
</table>
</panel>
and here's the new JS code
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/chartview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'],function(
TableView,
ChartView,
SearchManager,
mvc,
_
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
},
canRender: function(rowData) {
return true;
},
render: function($container, rowData) {
var SourceType_txt = _(rowData.cells).find(function (cell) {
return cell.field === 'sourcetype';
});
$container.append('<iframe src="/app/XYZ/table_row_expansion_child?hideChrome=true&hideEdit=true&hideTitle=true&form.prmSourceType='+ SourceType_txt.value + '" width="100%" height="400" border="0" frameborder="0"/>');
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
});
Did a quick test and both drilldowns work Ok.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

@azulgrana, the fix would be to use JS for drilldown for both Parent Table and extended Child Table. However, I noticed, issue with drilldown on child table as some of the times it is not even detecting that the Child table row has been clicked. Moreover the drilldown value from Parent to Child becomes incorrect.
In any case following is the approach I tried
Step 1: Remove the <drilldown>
section from expand_with_events
table and
Step 2: Add the following code for handling drilldown of the parent table as well as child table. Where isChildDrilldown
and isParentDrilldownInsideChild
are the semaphore values to detect which table was clicked and which drilldown prevented.
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
tableElement.on("click:cell",function(e){
e.preventDefault(); // Prevent redirecting to the Search app
if(isChildDrilldown==1 && (isParentDrilldownInsideChild==0 || isParentDrilldownInsideChild==1)){
isParentDrilldownInsideChild=isParentDrilldownInsideChild+1;
if(isParentDrilldownInsideChild==2){
isParentDrilldownInsideChild=0;
isChildDrilldown=0;
}
}else if(isChildDrilldown==0){
window.open('https://www.google.com','_blank');
}else{
isChildDrilldown=0;
isParentDrilldownInsideChild=0;
}
});
tableclick = mvc.Components.getInstance("TestTable");
tableclick.on("click:cell", function (e) {
e.preventDefault(); // Prevent redirecting to the Search app
window.open('https://www.yahoo.com','_blank');
isChildDrilldown=1;
});
| makeresults | eval message= "Happy Splunking!!!"
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Updated Simple XML and JS
<form script="custom_table_row_expansion.js">
<label>Table With Row Expansion</label>
<description>Show more information on click of expansion.</description>
<fieldset submitButton="false">
<input type="time" token="tokTime" searchWhenChanged="true">
<label></label>
<default>
<earliest>-24h@h</earliest>
<latest>now</latest>
</default>
</input>
</fieldset>
<row>
<panel>
<table id="expand_with_events">
<search>
<query>index=_internal | stats count by sourcetype</query>
<earliest>$tokTime.earliest$</earliest>
<latest>$tokTime.latest$</latest>
</search>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
</form>
Updated JS custom_table_row_expansion.js
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/chartview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'],function(
TableView,
ChartView,
SearchManager,
mvc,
_
){
console.log("Inside Table Row Expansion");
var isChildDrilldown=0;
var isParentDrilldownInsideChild=0;
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
this._searchManager = new SearchManager({
id: 'details-search-manager',
earliest_time: "$tokTime.earliest$",
latest_time: "$tokTime.latest$",
preview: false,
tokenDependencies: {},
},{tokens: true, tokenNamespace: "default"});
this._TableView = new TableView({
id: 'TestTable',
managerid: 'details-search-manager',
drilldown: 'cell'
});
},
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 sourcetypeCell = _(rowData.cells).find(function (cell) {
return cell.field === 'sourcetype';
});
//update the search with the sourcetype that we are interested in
this._searchManager.set({ search: 'index=_internal sourcetype=' + sourcetypeCell.value + '| head 5 | rename _raw as "Sample 5 rows" | table "Sample 5 rows"'});
// $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._TableView.render().el);
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
tableElement.on("click:cell",function(e){
e.preventDefault(); // Prevent redirecting to the Search app
if(isChildDrilldown==1 && (isParentDrilldownInsideChild==0 || isParentDrilldownInsideChild==1)){
isParentDrilldownInsideChild=isParentDrilldownInsideChild+1;
if(isParentDrilldownInsideChild==2){
isParentDrilldownInsideChild=0;
isChildDrilldown=0;
}
}else if(isChildDrilldown==0){
window.open('https://www.google.com','_blank');
}else{
isChildDrilldown=0;
isParentDrilldownInsideChild=0;
}
});
tableclick = mvc.Components.getInstance("TestTable");
tableclick.on("click:cell", function (e) {
e.preventDefault(); // Prevent redirecting to the Search app
window.open('https://www.yahoo.com','_blank');
isChildDrilldown=1;
});
});
| makeresults | eval message= "Happy Splunking!!!"
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks @niketnilay for the workaround, I'll give it a try. Do you think this is a bug?
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

I feel it is a bug with Table Row Expansion. Even with your code, you can see that some of the time yahoo.com will not open for all the rows when expanded.
In the debug mode I saw that it was picking up the sourcetype that I had not clicked that too multiple times.
| makeresults | eval message= "Happy Splunking!!!"
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks @niketnilay for all the testing and information! I might have to look into a diff approach
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think my workaround would be create a new dashboard for all the Child data and then iframe the child data.
Here's the XML for the new Child data
Table Row Expansion Child
<input type="text" token="prmSourceType">
<label>SourceType</label>
</input>
<panel>
<table>
<search>
<query>index=_internal sourcetype=$prmSourceType|s$ | table _raw</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
</search>
<option name="drilldown">cell</option>
<option name="refresh.display">progressbar</option>
<drilldown>
<link target="_blank">www.yahoo.com</link>
</drilldown>
</table>
</panel>
and here's the new JS code
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/chartview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'],function(
TableView,
ChartView,
SearchManager,
mvc,
_
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
},
canRender: function(rowData) {
return true;
},
render: function($container, rowData) {
var SourceType_txt = _(rowData.cells).find(function (cell) {
return cell.field === 'sourcetype';
});
$container.append('<iframe src="/app/XYZ/table_row_expansion_child?hideChrome=true&hideEdit=true&hideTitle=true&form.prmSourceType='+ SourceType_txt.value + '" width="100%" height="400" border="0" frameborder="0"/>');
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
});
Did a quick test and both drilldowns work Ok.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

@azulgrana if this works it is great. I was thinking that it is possible to create our own table row expansion and drilldown instead of using built-in. However it would involve considerable coding. Something in line with : https://answers.splunk.com/answers/324828/render-html-code-from-search-result-in-splunk-dash.html
However, I would explore this only in case above approach of yours does not work for you. So if it does do convert your comment to answer and accept the same 🙂
| makeresults | eval message= "Happy Splunking!!!"
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
done, thanks for your support @niketnilay
