Dashboards & Visualizations

How to set text formatting inside an HTML dashboard element for a TOKEN set by a search?

marycordova
SplunkTrust
SplunkTrust

Let's say I have a dashboard and it runs a search and when that search is done it sets a token $risk$.  

 

    <panel>
      <single depends="$hide$">
        <search>
          <progress>
            <unset token="risk"></unset>
          </progress>
          <done>
            <set token="risk">$result.risk$</set>
          </done>
          <query>| base search
| table risk
| head 1</query>
          <earliest>-15m@m</earliest>
          <latest>@m</latest>
        </search>
      </single>
      <html>
        <font size="4">
          <p style="text-align:left;">$risk$</p>
        </font>
      </html>
    </panel>

 

Now risk is a multi-value field and the strings for each value are long:

 

Risk thing 1 0.06 > population (standard deviation 0.02 + average 0.04)
Risk thing 2 0.74 > population (standard deviation 0.21 + average 0.30)
Risk thing 3 0.90 > population (standard deviation 0.20 + average 0.65)

 

 What happens when the token gets set and the html element renders risk is that the values turn into one long string:

 

Risk thing 1 0.06 > population (standard deviation 0.02 + average 0.04),Risk thing 2 0.74 > population (standard deviation 0.21 + average 0.30),Risk thing 3 0.90 > population (standard deviation 0.20 + average 0.65)

 

What I need is some way to format the token inside the html element.  I have tried to mvjoin the field using html tags as the delimiter but that does not work:

 

Risk thing 1 0.06 > population (standard deviation 0.02 + average 0.04)<br>Risk thing 2 0.74 > population (standard deviation 0.21 + average 0.30)<br>Risk thinkg 3 0.90 > population (standard deviation 0.20 + average 0.65)

 

I've tried different html tags around/inside the <p> and html elements and url encoded new line delimiters in the mv field and \n as a delimiter and who knows what else at this point.  

I want to be able to render the mv field values with a line break between them.  The only thing that kinda worked at all was the <pre> html tag, but I didn't really like that too much either.  

Labels (3)
0 Karma

niketnilay
Legend

@marycordova are you trying to do something like the use case in the following Answer of mine? https://community.splunk.com/t5/Dashboards-Visualizations/Render-HTML-code-from-search-result-in-Spl...I am not sure of the use case. Do you want to shorten the length of token?Once you do that what is the use of token.

Here is another answer with Table with multi-values which formats as Tile using CSS, in case you just want to format table as Tile using HTML, this would be better approach. https://community.splunk.com/t5/Dashboards-Visualizations/Is-there-a-way-to-display-more-than-20-cha...

Even if the above two do not fall into your use case, I think I would be able to help. However, I need to to know what is your use case. Table with Multivalue needs to be passed to a token, then what do you plan to do with the token!

@bowesmana check Answer 1 if you want to render HTML content from Search result as html panel.

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

bowesmana
Champion

@niketnilay thanks for that link - that's exactly what's needed - my JS skills are poor, but I figured it could be done quite simply in JS

0 Karma

niketnilay
Legend

@bowesmana glad you found it helpful. Be careful for filtering actual unescaped html elements be used directly as code in backend as it may open up for injection attacks. That is what by default tokens do (convert to string vaule rather than HTML elements). So best use case is when you know which html tags to be applied from the token and process only those through JS. Similar to what I have done for this answer. #br/# converts to <br/>, but any other html element will convert to text (not HTML).

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

marycordova
SplunkTrust
SplunkTrust

I want to insert newlines/linbreaks in the token.  See the difference between code block 2 and code block 3.  

0 Karma

niketnilay
Legend

@marycordova Try the following. The UI SPL adds a delimeter #br# that gets converted in JS as <br/>

Screen Shot 2020-09-16 at 12.32.55 AM.png

Following is the Simple XML Dashboard code:

 

<dashboard script="convert_token_to_html.js">
  <label>Risk Value to HTML</label>
  <row>
    <panel>
      <table>
        <search>
          <done>
            <set token="tokRiskHTML">$result.riskHTML|h$</set>
          </done>
          <query>| makeresults
| fields - _time
| eval risk="Risk thing 1 0.06 &gt; population (standard deviation 0.02 + average 0.04);Risk thing 2 0.74 &gt; population (standard deviation 0.21 + average 0.30);Risk thing 3 0.90 &gt; population (standard deviation 0.20 + average 0.65)"
| makemv risk delim=";"
| eval riskHTML=mvjoin(risk,"#br#")</query>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">100</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">none</option>
        <option name="percentagesRow">false</option>
        <option name="refresh.display">progressbar</option>
        <option name="rowNumbers">false</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <html>
        <div id="htmlPanelWithToken">
        </div>
      </html>
    </panel>
  </row>
</dashboard>

 

Following is the required JS convert_token_to_html.js

 

require([
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/simplexml/ready!'
], function($, mvc,) {
    var submittedTokens = mvc.Components.get('submitted');
    // Listen for a change to the token tokHTML value
    submittedTokens.on("change:tokRiskHTML", function(model, tokRiskHTML, options) {
        var tokRiskHTMLJS=submittedTokens.get("tokRiskHTML");
        if (tokRiskHTMLJS!==undefined)
        {
            tokRiskHTMLJS=tokRiskHTMLJS.replaceAll("#br#","<br/>");
            $("#htmlPanelWithToken").html(tokRiskHTMLJS);
        }
    });
});

 

PS: You may notice that in the UI, I have used html escaping for the token using $result.riskHTML|h$ which ensures that HTML elements are not passed as token value. The break line element <br/> is added directly through JS code.
Please try and confirm!

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

alacercogitatus
SplunkTrust
SplunkTrust

So - probably not possible with straight tokenization. I tried the |h formatter, but that didn't work. You'll need JS hook for this. But I've made it easy for you. Simply add this js snippet to the location specified, include it on the dashboard, update the p element (or any thing really), and there ya go! Renderable Elements based on tokens!

<app/appserver/static/js/token_render.js>

 

require([
                        "splunkjs/ready!",
                        "splunkjs/mvc/simplexml/ready!",
                        "splunkjs/mvc/utils",
                        "jquery"
                    ], function (mvc,
                                 ignored,
                                 splunkjsUtils,
                                 $
                    ) {
                            let tokens = mvc.Components.get("default");
                            let renderables = $('[token-render]');
                            for (var i = 0; i < renderables.length; i++){
                                let element = $(renderables[i]),
                                    element_data = element.data();
                                    tokens.on(`change:${element_data.token}`,
                                            (newTokenName, myToken, options) => {
                                                    element.html(tokens.get(element_data.token));
                                                });
                                element.html(tokens.get(element_data.token));
                            };
                    });

 

 

Dashboard:

 

<dashboard script="js/token_render.js">
  <label>Testing</label>
  <row>
    <panel>
      <single >
        <search>
          <query><![CDATA[
      |makeresults | eval r1 = random() %100 / 100, r2 = random() %100 / 100, r3 = split(r1.",".r2, ","), risk = mvjoin(r3, "<br/>")]]>
    </query>
          <progress>
            <unset token="risk"></unset>
          </progress>
          <done>
            <set token="risk">$result.risk$</set>
          </done>
          <earliest>-15m@m</earliest>
          <latest>@m</latest>
        </search>
      </single>
      <html>
        <font size="4">
          <p style="text-align:left;" token-render="true" data-token="risk" />
        </font>
        <font size="4">
          <p style="text-align:left;" token-render="true" data-token="risk" />
        </font>
      </html>
    </panel>
  </row>
</dashboard>

 

 

martin_mueller
SplunkTrust
SplunkTrust

It would be the `$risk|n$` token filter that would turn off the implicit `$risk|h$` filter that made it HTML-safe... but calling `|n` inside an HTML panel doesn't work ... probably for securitay.

bowesmana
Champion

@marycordova 

I can't solve the problem directly, as I have had exactly the same issue, with the same attempted solutions, but not found a good 'solution' for essentially a table inside HTML panels. I suspect Splunk is controlling the rendering of content.

However, I have used two html panels top and tailing a <table> where the table rows can then be rendered through CSS and or Javascript to achieve an acceptable outcome. There are some simple examples for row rendering in the dashboard examples app, where you can prettify the table somewhat.

I'd be interesting to know if there is a simple way to force Splunk to render token derived HTML content.

 

.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!