Dashboards & Visualizations

How to use dynamic checkbox in table?

silambarasu
Explorer

I need to create customize table in splunk. can you pls help how to implement that part and also attached the  sample image.it should be like that.

silambarasu_0-1679299901008.png

 

Labels (1)
0 Karma
1 Solution

kamlesh_vaghela
SplunkTrust
SplunkTrust

@silambarasu 

Can you please try this?

XML

<form script="multiselect_table.js" stylesheet="multiselect_table.css">
   <label>Multi-Select Table Rows Example</label>
   <row>
     <panel>
       <table id="myTable">
         <title>Panel A</title>
         <search id="SearchA">
           <query>| makeresults 
| eval _raw="{\"data\":[{\"id\":1,\"value\":\"test\"},{\"id\":2,\"value\":\"test2\"}]}" 
| rename comment as "upto now is data only" 
| spath path=data{} output=data 
| mvexpand data 
| spath input=data 
| eval CheckBox=id
| table CheckBox id value</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>
         <title>Ids Processed</title>
         <search id="SearchB">
           <query>| makeresults | eval SelectedRowValue="$mytoken$" | makemv delim="," SelectedRowValue | stats count by SelectedRowValue | table SelectedRowValue</query>
           <earliest>-15m</earliest>
           <latest>now</latest>
         </search>
         <option name="count">10</option>
         <option name="drilldown">none</option>
       </table>
     </panel>
   </row>
 </form>

 

Screenshot

 

Screenshot 2023-04-03 at 11.27.15 AM.png

 

Javascript file (multiselect_table.js)

 

 require([
         'underscore',
         'jquery',
         'splunkjs/mvc',
         'splunkjs/mvc/tableview',
         'splunkjs/mvc/simplexml/ready!'
     ], function (_, $, mvc, TableView) {
     // Access the "default" token model
     var tokens = mvc.Components.get("default");
     var selected_values_array = [];
     var isSelectAll = false;
     var searchAValues = [];
     var searchAFields = [];
     var fieldKey = "CheckBox";
     var fieldDataStoreKey="data-sort-key="+fieldKey;
     var submittedTokens = mvc.Components.get('submitted');
     console.log("This is Multi-select table JS");
     // Custom renderer for applying checkbox.
     var CustomRenderer = TableView.BaseCellRenderer.extend({
             canRender: function (cell) {
                 return _([fieldKey]).contains(cell.field);
             },
             render: function ($td, cell) {
                 // all_values_array.push(cell.value);
                 var cls = "checkbox";
                 if(isSelectAll) {
                     cls = "checkbox checked";
                 }
                 var a = $('<div>').attr({
                     "id": "chk-sourcetype_" + cell.value,
                     "value": cell.value
                 }).addClass(cls).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);
                         }
                     }
                 }).appendTo($td);
             }
         });
 
     //List of table ID
     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 CustomRenderer());
             tableView.table.render();
             tableView.on('rendered', function(view) {
                 setCheckAllCheckBox();
             });
             // setCheckAllCheckBox();
         });
     }
 
     var SearchA = mvc.Components.get("SearchA");
     var SearchAResults = SearchA.data("results");
     SearchAResults.on("data", function () {
         resultArray = SearchAResults.data().rows;
         searchAFields = SearchAResults.data().fields;
         var keyIndex=searchAFields.indexOf(fieldKey);
         searchAValues = [];
         $.each(resultArray, function (index, value) { 
             searchAValues[index]=value[keyIndex];
         })
     });
 
     SearchA.on('search:start', function (properties) {
         isSelectAll = false;
         tokens.unset("mytoken");
         tokens.set("mytoken", "");
         submittedTokens.set(tokens.toJSON());
     });
     SearchA.on('search:done', function (properties) {
         console.log("in search done",properties);
     });
 
     // Disabling button while search is running
     var SearchB = mvc.Components.get('SearchB');
     SearchB.on('search:start', function (properties) {
         $("#mybutton").attr('disabled', true);
     });
 
     SearchB.on('search:done', function (properties) {
         $("#mybutton").attr('disabled', false);
     });
     var sto;
     function setCheckAllCheckBox()
     {
         var a = $("["+fieldDataStoreKey+"]");
         a.html("");
         var cls = "checkbox";
         if(isSelectAll) {
             cls = "checkbox checked";
         }
         var temp = $('<div>').attr({
             "id": "chk-sourcetype-All",
             "value": "All"
         }).addClass(cls).click(function () {
             if ($(this).attr('class') === "checkbox") {
                 $(this).removeClass();
                 $(this).addClass("checkbox checked");
                 isSelectAll = true;
             } else {
                 $(this).removeClass();
                 $(this).addClass("checkbox");
                 isSelectAll = false;
             }
             checkUnCheckAllCheckboxes();
         }).appendTo(a);
         $("["+fieldDataStoreKey+"]").parent().removeAttr("class");
         $("["+fieldDataStoreKey+"]").removeAttr("data-sort-key");
     }
     function checkUnCheckAllCheckboxes(){
         var cls = "checkbox";
         selected_values_array = [];
         if(isSelectAll) {
             cls = "checkbox checked";
             $.each(searchAValues, function (index, value) { 
                 selected_values_array.push(value);
             })
         }
         $('[id^="chk-sourcetype_"]').removeClass();
         $('[id^="chk-sourcetype_"]').addClass(cls);
     }

     function updateDataOnServerSide() {
        var service = mvc.createService({ owner: "nobody" });
        //send data to server
        console.log(selected_values_array.join());
        var params = selected_values_array.join();
        service.request("/services/my-api-path","POST", {}, {}, JSON.stringify(params), {'Content-Type': 'application/json'}, function(err, resp) {
            // Handle response    
            if(resp != null){
              if(resp.status == 200){  
                //do something
              } else {
                //do something with status !=200
              }
            }
            // Handle error
            if(err != null){
              //handle error
            }
          });
     }
     
     $(document).ready(function () {
         //setting up tokens with selected value.
         $("#mybutton").on("click", function (e) {
             e.preventDefault();
             updateDataOnServerSide();
             tokens.set("mytoken", selected_values_array.join());
             submittedTokens.set(tokens.toJSON());
             $("#mybutton").attr('disabled', true);
         });
         // setCheckAllCheckBox();
         setTimeout(function(){
             setCheckAllCheckBox();
         },2000);
     });
 });

 

CSS (multiselect_table.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);
 }

 

Note: Up to now is just a reference code, just copy and paste.  

The next steps:

  1. Follow the below link and create a server-side logic by creating a custom endpoint in Splunk.
    1. https://community.splunk.com/t5/Dashboards-Visualizations/How-to-create-Javascript-for-a-button-on-a...
  2. Then Execute the custom API from the dashboard.
    1. You need to update the API path in updateDataOnServerSide function in multiselect_table.js file.
    2. You can also handle the HTTP errors in dashboard UI as well.
  3.  You need to change the search query in the dashboard by providing your index and source type also.

 

 

I hope this will help you. 

 

Thanks
KV
If any of my replies help you to solve the problem Or gain knowledge, an upvote would be appreciated.

 

View solution in original post

0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

@silambarasu 

Can you please try this?

XML

<form script="multiselect_table.js" stylesheet="multiselect_table.css">
   <label>Multi-Select Table Rows Example</label>
   <row>
     <panel>
       <table id="myTable">
         <title>Panel A</title>
         <search id="SearchA">
           <query>| makeresults 
| eval _raw="{\"data\":[{\"id\":1,\"value\":\"test\"},{\"id\":2,\"value\":\"test2\"}]}" 
| rename comment as "upto now is data only" 
| spath path=data{} output=data 
| mvexpand data 
| spath input=data 
| eval CheckBox=id
| table CheckBox id value</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>
         <title>Ids Processed</title>
         <search id="SearchB">
           <query>| makeresults | eval SelectedRowValue="$mytoken$" | makemv delim="," SelectedRowValue | stats count by SelectedRowValue | table SelectedRowValue</query>
           <earliest>-15m</earliest>
           <latest>now</latest>
         </search>
         <option name="count">10</option>
         <option name="drilldown">none</option>
       </table>
     </panel>
   </row>
 </form>

 

Screenshot

 

Screenshot 2023-04-03 at 11.27.15 AM.png

 

Javascript file (multiselect_table.js)

 

 require([
         'underscore',
         'jquery',
         'splunkjs/mvc',
         'splunkjs/mvc/tableview',
         'splunkjs/mvc/simplexml/ready!'
     ], function (_, $, mvc, TableView) {
     // Access the "default" token model
     var tokens = mvc.Components.get("default");
     var selected_values_array = [];
     var isSelectAll = false;
     var searchAValues = [];
     var searchAFields = [];
     var fieldKey = "CheckBox";
     var fieldDataStoreKey="data-sort-key="+fieldKey;
     var submittedTokens = mvc.Components.get('submitted');
     console.log("This is Multi-select table JS");
     // Custom renderer for applying checkbox.
     var CustomRenderer = TableView.BaseCellRenderer.extend({
             canRender: function (cell) {
                 return _([fieldKey]).contains(cell.field);
             },
             render: function ($td, cell) {
                 // all_values_array.push(cell.value);
                 var cls = "checkbox";
                 if(isSelectAll) {
                     cls = "checkbox checked";
                 }
                 var a = $('<div>').attr({
                     "id": "chk-sourcetype_" + cell.value,
                     "value": cell.value
                 }).addClass(cls).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);
                         }
                     }
                 }).appendTo($td);
             }
         });
 
     //List of table ID
     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 CustomRenderer());
             tableView.table.render();
             tableView.on('rendered', function(view) {
                 setCheckAllCheckBox();
             });
             // setCheckAllCheckBox();
         });
     }
 
     var SearchA = mvc.Components.get("SearchA");
     var SearchAResults = SearchA.data("results");
     SearchAResults.on("data", function () {
         resultArray = SearchAResults.data().rows;
         searchAFields = SearchAResults.data().fields;
         var keyIndex=searchAFields.indexOf(fieldKey);
         searchAValues = [];
         $.each(resultArray, function (index, value) { 
             searchAValues[index]=value[keyIndex];
         })
     });
 
     SearchA.on('search:start', function (properties) {
         isSelectAll = false;
         tokens.unset("mytoken");
         tokens.set("mytoken", "");
         submittedTokens.set(tokens.toJSON());
     });
     SearchA.on('search:done', function (properties) {
         console.log("in search done",properties);
     });
 
     // Disabling button while search is running
     var SearchB = mvc.Components.get('SearchB');
     SearchB.on('search:start', function (properties) {
         $("#mybutton").attr('disabled', true);
     });
 
     SearchB.on('search:done', function (properties) {
         $("#mybutton").attr('disabled', false);
     });
     var sto;
     function setCheckAllCheckBox()
     {
         var a = $("["+fieldDataStoreKey+"]");
         a.html("");
         var cls = "checkbox";
         if(isSelectAll) {
             cls = "checkbox checked";
         }
         var temp = $('<div>').attr({
             "id": "chk-sourcetype-All",
             "value": "All"
         }).addClass(cls).click(function () {
             if ($(this).attr('class') === "checkbox") {
                 $(this).removeClass();
                 $(this).addClass("checkbox checked");
                 isSelectAll = true;
             } else {
                 $(this).removeClass();
                 $(this).addClass("checkbox");
                 isSelectAll = false;
             }
             checkUnCheckAllCheckboxes();
         }).appendTo(a);
         $("["+fieldDataStoreKey+"]").parent().removeAttr("class");
         $("["+fieldDataStoreKey+"]").removeAttr("data-sort-key");
     }
     function checkUnCheckAllCheckboxes(){
         var cls = "checkbox";
         selected_values_array = [];
         if(isSelectAll) {
             cls = "checkbox checked";
             $.each(searchAValues, function (index, value) { 
                 selected_values_array.push(value);
             })
         }
         $('[id^="chk-sourcetype_"]').removeClass();
         $('[id^="chk-sourcetype_"]').addClass(cls);
     }

     function updateDataOnServerSide() {
        var service = mvc.createService({ owner: "nobody" });
        //send data to server
        console.log(selected_values_array.join());
        var params = selected_values_array.join();
        service.request("/services/my-api-path","POST", {}, {}, JSON.stringify(params), {'Content-Type': 'application/json'}, function(err, resp) {
            // Handle response    
            if(resp != null){
              if(resp.status == 200){  
                //do something
              } else {
                //do something with status !=200
              }
            }
            // Handle error
            if(err != null){
              //handle error
            }
          });
     }
     
     $(document).ready(function () {
         //setting up tokens with selected value.
         $("#mybutton").on("click", function (e) {
             e.preventDefault();
             updateDataOnServerSide();
             tokens.set("mytoken", selected_values_array.join());
             submittedTokens.set(tokens.toJSON());
             $("#mybutton").attr('disabled', true);
         });
         // setCheckAllCheckBox();
         setTimeout(function(){
             setCheckAllCheckBox();
         },2000);
     });
 });

 

CSS (multiselect_table.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);
 }

 

Note: Up to now is just a reference code, just copy and paste.  

The next steps:

  1. Follow the below link and create a server-side logic by creating a custom endpoint in Splunk.
    1. https://community.splunk.com/t5/Dashboards-Visualizations/How-to-create-Javascript-for-a-button-on-a...
  2. Then Execute the custom API from the dashboard.
    1. You need to update the API path in updateDataOnServerSide function in multiselect_table.js file.
    2. You can also handle the HTTP errors in dashboard UI as well.
  3.  You need to change the search query in the dashboard by providing your index and source type also.

 

 

I hope this will help you. 

 

Thanks
KV
If any of my replies help you to solve the problem Or gain knowledge, an upvote would be appreciated.

 

0 Karma

silambarasu
Explorer

it's working as expected... Thnks Kamlesh

0 Karma

silambarasu
Explorer

how to pass the JSON response from JS to XML.I need to put it serach query

| eval _raw=**JSON response**
Tags (1)
0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

@silambarasu 

Just set a token in JS and use it in XML. take a reference of mytoken in above code.

KV

Get Updates on the Splunk Community!

Splunk Certification Support Alert | Pearson VUE Outage

Splunk Certification holders and candidates!  Please be advised of an upcoming system maintenance period for ...

Enterprise Security Content Update (ESCU) | New Releases

In September, the Splunk Threat Research Team had two releases of new security content via the Enterprise ...

New in Observability - Improvements to Custom Metrics SLOs, Log Observer Connect & ...

The latest enhancements to the Splunk observability portfolio deliver improved SLO management accuracy, better ...