Dashboards & Visualizations

JavaScript with XML Coding

kartm2020
Communicator

Hi

I want to search the multiple keyword in the field and it needs to be highlighted in the dashboard with different color

I have achieved to search one keyword word at a time. Can anyone help me to do it.
I have pasted the JS in static folder of app

XML code:

<form script="highlightToken.js">
  <label>Highlight_text</label>
  <fieldset>
    <input type="time" token="field1">
      <label></label>
      <default>
        <earliest>-5m@m</earliest>
        <latest>now</latest>
      </default>
    </input>
    <input type="text" token="highlightToken" searchWhenChanged="true">
      <label>Search Word</label>
      <default>splunk*</default>
      <initialValue>searchword</initialValue>
    </input>
  </fieldset>
  <row>
    <panel>
      <title>$highlightToken$</title>
      <table id="highlightTable1">
        <search id="highlightSearch1">
          <query>index=_internal
| stats count by sourcetype</query>

          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>

        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
    <panel>
      <table id="highlightTable2">
        <search id="highlightSearch2">
          <query>index=_internal 
| stats count by sourcetype
| head 5</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <table id="highlightTable3">
        <search id="highlightSearch3">
          <query>index=_internal 
| stats count by sourcetype
| head 5</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
    <panel>
      <table id="highlightTable4">
        <search id="highlightSearch4">
          <query>index=_internal sourcetype="splunkd"
| stats count by sourcetype
| head 5</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <table id="highlightTable5">
        <search id="highlightSearch5">
          <query>index=_internal 
| stats count by sourcetype
| head 5</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
  </row>
</form>

Javascript:
require([
"underscore",
"jquery",
"splunkjs/mvc",
"splunkjs/mvc/searchmanager",
"splunkjs/mvc/tableview",
"splunkjs/mvc/simplexml/ready!"
], function (, $, mvc, SearchManager, TableView) {
var defaultTokenModel = mvc.Components.get("default");
// var strHighlightText = ""
var strHighlightText = defaultTokenModel.get("highlightToken");
var customCellRenderer = TableView.BaseCellRenderer.extend({
canRender: function (cell) {
return cell.field !== "_time";
},
render: function ($td, cell) {
var strText = cell.value;
if (strHighlightText !== "*" && strHighlightText !== "") {
var regEx = new RegExp(strHighlightText, "gi");
strText = strText.replace(regEx, '$&');
}
$td.addClass('string').html(
.template(strText));
}
});
function highlightTable() {
var maxCount = 6;
for (i = 0; i < maxCount; i++) {
var tableItem = mvc.Components.get("highlightTable" + i);
if (typeof (strHighlightText) !== "undefined" && typeof (tableItem) !== "undefined") {
var search = mvc.Components.get("highlightSearch" + i);
if (search !== undefined) {
console.log("highlightSearch:", i)
search.startSearch();
}
console.log("highlightToken:", strHighlightText, " tableId:", i)
tableItem.getVisualization(function (tableView) {
tableView.addCellRenderer(new customCellRenderer());
});
}
}
}
defaultTokenModel.on("change:highlightToken", function (model, value, options) {
if (typeof (value) !== "undefined" || value !== "$value$") {
strHighlightText = value;
highlightTable();
}
});
highlightTable();
});

0 Karma

kartm2020
Communicator

how to pass the multiple values into array with comma seperated.

For example, I am giving the string as splunk,web,access. it should store the value as a[0] = splunk, a[1] = web a[2]= access

0 Karma

kartm2020
Communicator

Can anyone help me on this ?

0 Karma

niketn
Legend

@kartm2020 if this is based on my previous answer: https://answers.splunk.com/answers/636948/how-to-add-css-class-to-table-field-by-input-in-sp.html, then that was created only for Single Table using specific table ID i.e. table1.

  var tableView=mvc.Components.get("table1");

In case you want to apply the same logic to multiple tables, you can try the following approaches:
1. In JS keep is string array of table IDs and iterate through table IDs to access respective TableView and add your custom cell renderer. Simple but required JS change each time new table is added or removed.
2. If you want to keep the logic dynamic for all table ( ** I am documenting this approach to iterate through all tables in SimpleXML and to extended each one of them using SimpleXML JS Extension and SplunkJS dynamically ** )

a) You would need to iterate through all Splunk Elements using mvc.Components.getInstances(). Refer to older answer: https://answers.splunk.com/answers/129142/changing-multiple-tables-in-simplexml-using-splunkjs.html
b) You would need to identify whether it is TableView element. If so, extend the Base Cell Renderer, when text box value is changed.
c) In order to refresh the table add a dummy token dependency each time custom Cell Renderer is added. There are several examples and ways to do this. One such example for reference: https://answers.splunk.com/answers/667232/how-to-force-rerendering-tableview-from-javascript.html

PS: Since the search is re-run for table re-render on changing the text box value, consider loadjob kind of option to display the results in table then refresh using token set in JS on Extending the Table Cell Render. Or else the solution will have to be purely jQuery based assuming Queries complete before Text Box value is changed.

alt text

Following is the Simple XML Dashboard code:

<form script="highlightToken.js">
  <label>Highlight selected text in all tables</label>
  <init>
    <set token="tokRefresh">true</set>
  </init>
  <fieldset submitButton="true" autoRun="false">
    <input type="time" token="field1" searchWhenChanged="false">
      <label></label>
      <default>
        <earliest>-1h@h</earliest>
        <latest>now</latest>
      </default>
    </input>
    <input type="text" token="tokFilter" searchWhenChanged="false">
      <label>Search Word</label>
      <default>splunk*</default>
      <initialValue>searchword</initialValue>
    </input>
  </fieldset>
  <row>
    <panel>
      <table id="highlightTable1">
        <search id="highlightSearch1">
          <query>index=_internal
 | stats count by sourcetype
 | fields - "$tokRefresh$"</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
          <refresh>1m</refresh>
          <refreshType>delay</refreshType>
        </search>
        <option name="count">5</option>
        <option name="drilldown">none</option>
      </table>
    </panel>
    <panel>
      <table id="highlightTable2">
        <search id="highlightSearch2">
          <query>index=_internal 
 | stats count by sourcetype
 | head 5
 | fields - "$tokRefresh$"</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
          <refresh>30s</refresh>
          <refreshType>delay</refreshType>
        </search>
        <option name="count">5</option>
        <option name="drilldown">none</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <table id="highlightTable3">
        <search id="highlightSearch3">
          <query>index=_internal 
 | stats count by sourcetype
 | head 5
| fields - "$tokRefresh$" </query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="count">5</option>
        <option name="drilldown">none</option>
      </table>
    </panel>
    <panel>
      <table id="highlightTable4">
        <search id="highlightSearch4">
          <query>index=_internal sourcetype="splunkd"
 | stats count by sourcetype
 | head 5
| fields - "$tokRefresh$" </query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="count">5</option>
        <option name="drilldown">none</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <table id="highlightTable5">
        <search id="highlightSearch5">
          <query>index=_internal 
 | stats count by sourcetype
 | head 5
| fields - "$tokRefresh$" </query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
  </row>
</form>

Following is the required JS file highlightToken.js to be placed under your Splunk app's appserver/static folder.

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

    var submittedTokenModel = mvc.Components.get("submitted");
    var tableView;
    var tokRefresh = "refreshCounter1"
    var refreshCounter = 0;
    var strRefresh = "refresh1";
    var strFilterText = ""

    var CustomHighlightRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            //Applied to message column in the Table 
            return cell.field === "sourcetype";
        },
        render: function($td, cell) {
            var strText = cell.value;
            var regEx = new RegExp(strFilterText, "gi");
            //Apply regular expression to replace Filter Text with html content bold font and red color
            strText = strText.replace(regEx, '<b style="color:red;">$&</b>');
            // Add html content to table cell of string class
            $td.addClass('string').html(_.template(strText));
        }
    });

    // When Text box input value changes handle tokFilter 
    submittedTokenModel.on("change:tokFilter", function(newtokFilter, tokFilter, options) {
        // Only if tokFilter has value apply Custom Table Render
        // Since token tokFilter is used in table query Table is supposed to render again 
        if (tokFilter !== undefined || tokFilter !== "$value$") {
            strFilterText = tokFilter;
            $.each(mvc.Components.getInstances(), function(i, tableView) {
                if (tableView instanceof TableView) {
                    // Register custom cell renderer, the table will re-render automatically
                    var customRenderer = tableView.getCellRenderers();
                    tableView.removeCellRenderer(customRenderer);
                    tableView.addCellRenderer(new CustomHighlightRenderer());
                    if (refreshCounter == 2) {
                        refreshCounter = refreshCounter + 1;
                        strRefresh = strRefresh + refreshCounter.toString();
                    } else {
                        refreshCounter = 1;
                        strRefresh = strRefresh + refreshCounter.toString();
                    }
                    submittedTokenModel.set("tokRefresh", strRefresh);
                }
            });
        }
    });
});
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

kartm2020
Communicator

It is working as like mine. However, I want to search multiple word in the field!

Ex: Splunk,metrics,scheduler

Please find the below url:

https://ibb.co/M5H7tPd

0 Karma

kartm2020
Communicator

@niketnilay. Please look into it

0 Karma

niketn
Legend

@kartm2020 your logic will still remain the same. Instead of assigning tokFilter to strFilterText, you will need to

  1. Use string array and iterate through it to assign to filter text loop OR
  2. Split comma separated values and iterate through filter text loop. This would be pure JavaScript code nothing related to Splunk, so if you are good with JS figure out yourself or have a JS coder look into the same. Unfortunately our intent is to give pointers to solution not to spoon-feed.

Keep Splunking and Keep Learning!

Please accept/upvote the answer if it helped.

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

kartm2020
Communicator

I have found the solution on my own. I have asked some doubts but you havent given the clear answer instead you have given same logic what i have wriiten it already in JS. i just need a help for improvisation. I am not expecting spoon feed.

You answer was not helped me..THANK YOU!

0 Karma

niketn
Legend

@kartm2020 I am glad you were able to find solution on your own and that's the best way to learn! We also like to help community by documenting the solution to assist other Splunkers facing similar issue. Please post as answer and accept the same.

The reason why I posted only hints for iterating through comma separated string in JS is because it is not Splunk related problem, it is pure JavaScript and simple google like Iterate through comma separated string in JavaScript helps.

PS: The code you have posted in your question as I had stated is also after one of my older answers. I chose to extend it because, I dont think you will find mvc.Components.getInstances() to iterate through all the TableView objects on Splunk Answers or Splunk Docs or Splunk Blogs.

Thanks for making me feel that I should not be spending my time on documenting or assisting Splunkers on Answers with the problems that has not been solved before or people say is not possible!

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma
Get Updates on the Splunk Community!

Welcome to the Splunk Community!

(view in My Videos) We're so glad you're here! The Splunk Community is place to connect, learn, give back, and ...

Tech Talk | Elevating Digital Service Excellence: The Synergy of Splunk RUM & APM

Elevating Digital Service Excellence: The Synergy of Real User Monitoring and Application Performance ...

Adoption of RUM and APM at Splunk

    Unleash the power of Splunk Observability   Watch Now In this can't miss Tech Talk! The Splunk Growth ...