Hi there,
How would I select an entire row in a table from a dashboard and use each field/cell from that table to populate another panel/table when selected? Essentially just cloning whatever rows i select from one panel -> hit submit -> selected rows go to another panel.
Any thoughts on how to achieve this?
Thanks!
You are lucky. I'm working on the same for another purpose but I'm sure you will achieve the same by using the below code.
Note: This code is now Specific to index=_internal | stats count by sourcetype | eval recNumber=1 | accum recNumber | table recNumber sourcetype count
- this - search. So you have to manual change for your search. In your search you have to add | eval recNumber=1 | accum recNumber
and put this as checkbox column. find recNumber
in javascript which will let you know at how many places you have to make changes. Another field is sourcetype
, this will also help you.
XML
<dashboard script="multiselect_table_data.js" stylesheet="multiselect_table_data.css">
<label>Multi-Select Table Rows Example</label>
<row>
<panel>
<table id="myTable">
<title>Panel A</title>
<search id="myPrimarySearch">
<query>index=_internal | stats count by sourcetype | eval recNumber=1 | accum recNumber | table recNumber sourcetype count</query>
<earliest>-15m</earliest>
<latest>now</latest>
</search>
<option name="count">10</option>
<option name="drilldown">row</option>
<option name="refresh.display">progressbar</option>
<drilldown>
<condition field="*"></condition>
</drilldown>
</table>
</panel>
<panel>
<html>
<div>
<input type="button" id="mybutton" value="Submit"/>
</div>
</html>
</panel>
<panel>
<table id="secondTable">
<title>Panel B</title>
<search id="mysearch">
<query> $searchQuery$ </query>
<earliest>-15m</earliest>
<latest>now</latest>
</search>
<option name="count">10</option>
<option name="drilldown">none</option>
</table>
</panel>
</row>
</dashboard>
multiselect_table_data.js
require([
'underscore',
'jquery',
'splunkjs/mvc',
'splunkjs/mvc/tableview',
'splunkjs/mvc/simplexml/ready!'
], function (_, $, mvc, TableView) {
// Access the "default" token model
var defaultTokenModel = mvc.Components.get("default");
var selected_values_array = [];
var submittedTokens = mvc.Components.get('submitted');
var myPrimarySearchData;
var myPrimarySearch = mvc.Components.get('myPrimarySearch');
var myPrimarySearch_results = myPrimarySearch.data("preview");
//console.log("myPrimarySearch_results",myPrimarySearch_results);
var myPrimarySearchArray = [];
myPrimarySearch_results.on("data", function() {
myPrimarySearchData = myPrimarySearch_results.data();
});
console.log("This is Multi-select table JS");
// Custom renderer for applying checkbox.
var FirstTableRenderer = TableView.BaseCellRenderer.extend({
canRender: function (cell) {
return _(['recNumber']).contains(cell.field);
},
render: function ($td, cell) {
var a = $('<div>').attr({
"id": "chk-sourcetype" + cell.value,
"value": cell.value
}).addClass('checkbox').click(function () {
if ($(this).attr('class') === "checkbox") {
selected_values_array.push($(this).attr('value'));
$(this).removeClass();
$(this).addClass("checkbox checked");
} else {
$(this).removeClass();
$(this).addClass("checkbox");
var i = selected_values_array.indexOf($(this).attr('value'));
if (i != -1) {
selected_values_array.splice(i, 1);
}
}
});
if(selected_values_array.indexOf(cell.value) > -1) {
a = a.addClass("checked");
}
a.appendTo($td);
}
});
var sh = mvc.Components.get("myTable");
if (typeof(sh) != "undefined") {
sh.getVisualization(function (tableView) {
// Add custom cell renderer and force re-render
tableView.table.addCellRenderer(new FirstTableRenderer());
tableView.table.render();
});
}
// Disabling button while search is running
var mysearch = mvc.Components.get('mysearch');
mysearch.on('search:start', function (properties) {
$("#mybutton").attr('disabled', true);
});
mysearch.on('search:done', function (properties) {
$("#mybutton").attr('disabled', false);
});
$(document).ready(function () {
//setting up tokens with selected value.
$("#mybutton").on("click", function (e) {
e.preventDefault();
setArrayInToken();
});
});
function setArrayInToken(){
defaultTokenModel.set("mytoken", selected_values_array.join());
submittedTokens.set(defaultTokenModel.toJSON());
}
defaultTokenModel.on("change:mytoken", function(formQuery, indexName) {
var newQuery = ' | makeresults | eval recNumber="'+indexName+'" | makemv delim="," recNumber | stats count by recNumber | eval sourcetype=recNumber,count=recNumber | table sourcetype count';
console.log(newQuery);
defaultTokenModel.set('searchQuery', newQuery);
});
var SecondTableRenderer = TableView.BaseCellRenderer.extend({
canRender: function (cell) {
return _(['recNumber','sourcetype','count']).contains(cell.field);
},
render: function ($td, cell) {
var rows = myPrimarySearchData.rows;
var fields = myPrimarySearchData.fields;
var dataIndex = fields.indexOf(cell.field);
var cellValue=rows[cell.value - 1][dataIndex];
$td.addClass("string");
var a = $('<div>'+cellValue+'</div>').appendTo($td);
}
});
var sh = mvc.Components.get("secondTable");
if (typeof(sh) != "undefined") {
sh.getVisualization(function (tableView) {
// Add custom cell renderer and force re-render
tableView.table.addCellRenderer(new SecondTableRenderer());
tableView.table.render();
});
}
});
multiselect_table_data.css
/* The standalone checkbox square*/
.checkbox {
width:20px;
height:20px;
border: 1px solid #000;
display: inline-block;
}
/* This is what simulates a checkmark icon */
.checkbox.checked:after {
content: '';
display: block;
width: 4px;
height: 7px;
/* "Center" the checkmark */
position:relative;
top:4px;
left:7px;
border: solid #000;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
You are lucky. I'm working on the same for another purpose but I'm sure you will achieve the same by using the below code.
Note: This code is now Specific to index=_internal | stats count by sourcetype | eval recNumber=1 | accum recNumber | table recNumber sourcetype count
- this - search. So you have to manual change for your search. In your search you have to add | eval recNumber=1 | accum recNumber
and put this as checkbox column. find recNumber
in javascript which will let you know at how many places you have to make changes. Another field is sourcetype
, this will also help you.
XML
<dashboard script="multiselect_table_data.js" stylesheet="multiselect_table_data.css">
<label>Multi-Select Table Rows Example</label>
<row>
<panel>
<table id="myTable">
<title>Panel A</title>
<search id="myPrimarySearch">
<query>index=_internal | stats count by sourcetype | eval recNumber=1 | accum recNumber | table recNumber sourcetype count</query>
<earliest>-15m</earliest>
<latest>now</latest>
</search>
<option name="count">10</option>
<option name="drilldown">row</option>
<option name="refresh.display">progressbar</option>
<drilldown>
<condition field="*"></condition>
</drilldown>
</table>
</panel>
<panel>
<html>
<div>
<input type="button" id="mybutton" value="Submit"/>
</div>
</html>
</panel>
<panel>
<table id="secondTable">
<title>Panel B</title>
<search id="mysearch">
<query> $searchQuery$ </query>
<earliest>-15m</earliest>
<latest>now</latest>
</search>
<option name="count">10</option>
<option name="drilldown">none</option>
</table>
</panel>
</row>
</dashboard>
multiselect_table_data.js
require([
'underscore',
'jquery',
'splunkjs/mvc',
'splunkjs/mvc/tableview',
'splunkjs/mvc/simplexml/ready!'
], function (_, $, mvc, TableView) {
// Access the "default" token model
var defaultTokenModel = mvc.Components.get("default");
var selected_values_array = [];
var submittedTokens = mvc.Components.get('submitted');
var myPrimarySearchData;
var myPrimarySearch = mvc.Components.get('myPrimarySearch');
var myPrimarySearch_results = myPrimarySearch.data("preview");
//console.log("myPrimarySearch_results",myPrimarySearch_results);
var myPrimarySearchArray = [];
myPrimarySearch_results.on("data", function() {
myPrimarySearchData = myPrimarySearch_results.data();
});
console.log("This is Multi-select table JS");
// Custom renderer for applying checkbox.
var FirstTableRenderer = TableView.BaseCellRenderer.extend({
canRender: function (cell) {
return _(['recNumber']).contains(cell.field);
},
render: function ($td, cell) {
var a = $('<div>').attr({
"id": "chk-sourcetype" + cell.value,
"value": cell.value
}).addClass('checkbox').click(function () {
if ($(this).attr('class') === "checkbox") {
selected_values_array.push($(this).attr('value'));
$(this).removeClass();
$(this).addClass("checkbox checked");
} else {
$(this).removeClass();
$(this).addClass("checkbox");
var i = selected_values_array.indexOf($(this).attr('value'));
if (i != -1) {
selected_values_array.splice(i, 1);
}
}
});
if(selected_values_array.indexOf(cell.value) > -1) {
a = a.addClass("checked");
}
a.appendTo($td);
}
});
var sh = mvc.Components.get("myTable");
if (typeof(sh) != "undefined") {
sh.getVisualization(function (tableView) {
// Add custom cell renderer and force re-render
tableView.table.addCellRenderer(new FirstTableRenderer());
tableView.table.render();
});
}
// Disabling button while search is running
var mysearch = mvc.Components.get('mysearch');
mysearch.on('search:start', function (properties) {
$("#mybutton").attr('disabled', true);
});
mysearch.on('search:done', function (properties) {
$("#mybutton").attr('disabled', false);
});
$(document).ready(function () {
//setting up tokens with selected value.
$("#mybutton").on("click", function (e) {
e.preventDefault();
setArrayInToken();
});
});
function setArrayInToken(){
defaultTokenModel.set("mytoken", selected_values_array.join());
submittedTokens.set(defaultTokenModel.toJSON());
}
defaultTokenModel.on("change:mytoken", function(formQuery, indexName) {
var newQuery = ' | makeresults | eval recNumber="'+indexName+'" | makemv delim="," recNumber | stats count by recNumber | eval sourcetype=recNumber,count=recNumber | table sourcetype count';
console.log(newQuery);
defaultTokenModel.set('searchQuery', newQuery);
});
var SecondTableRenderer = TableView.BaseCellRenderer.extend({
canRender: function (cell) {
return _(['recNumber','sourcetype','count']).contains(cell.field);
},
render: function ($td, cell) {
var rows = myPrimarySearchData.rows;
var fields = myPrimarySearchData.fields;
var dataIndex = fields.indexOf(cell.field);
var cellValue=rows[cell.value - 1][dataIndex];
$td.addClass("string");
var a = $('<div>'+cellValue+'</div>').appendTo($td);
}
});
var sh = mvc.Components.get("secondTable");
if (typeof(sh) != "undefined") {
sh.getVisualization(function (tableView) {
// Add custom cell renderer and force re-render
tableView.table.addCellRenderer(new SecondTableRenderer());
tableView.table.render();
});
}
});
multiselect_table_data.css
/* The standalone checkbox square*/
.checkbox {
width:20px;
height:20px;
border: 1px solid #000;
display: inline-block;
}
/* This is what simulates a checkmark icon */
.checkbox.checked:after {
content: '';
display: block;
width: 4px;
height: 7px;
/* "Center" the checkmark */
position:relative;
top:4px;
left:7px;
border: solid #000;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
Awesome!!! Thank you a lot!!!
@kamlesh_vaghela awesome stuff this is really cool! Thanks! Do you have any tricks up your sleeve to send a sparkline across from table 1 to table 2 =D ..i have some timechart sparkline graphs in table 1 and in table 2 they are just the numerical values..