Dashboards & Visualizations

How to add a click event to a table?

LuiesCui
Communicator

Hi guys, I have a problem with drilling down the table and I really need ur help!
I have a simple xml dashboard here:

<row>
    <panel>
      <table id="table">
        <search>
          <query>| inputlookup worklog.csv | table solution remark </query>
          <earliest>0</earliest>
          <latest></latest>
        </search>
        <option name="wrap">true</option>
        <option name="rowNumbers">false</option>
        <option name="drilldown">row</option>
        <option name="dataOverlayMode">none</option>
        <option name="count">10</option>
        <fields>solution</fields>
        <drilldown>
          <set token="remark">$row.remark$</set>
        </drilldown>
      </table>
    </panel>
    <panel id="chart1">
      <html>
        <div>
          <p id="Remark">$remark$</p>
        </div>  
      </html>
    </panel>
  </row>

As u can see, there is a table and a div in the dashboard. What I wanna do is the content of the div will be changed and get the value of some fields of the search when I click any cells in the table. It works well but is not perfect. Before I click the table, the content of div will be "$remark$", which makes the dashboard really weird. In some events the column of "remark" return no result and the content of div will be "null". So I wrote a js to help this.

var deps = [
    "splunkjs/ready!",
    "splunkjs/mvc/searchmanager"
];

var db_boo = true;
var qt_boo = true;

require(deps, function(mvc) {
    var table = document.getElementById("table");
    var remark = document.getElementById("Remark");
    table.on('click:cell', function(properties) {
        if(remark.innerHTML=="null"||remark.innerHTML=="$remark$"){
            remark.innerHTML="";
        }
    });
})

But after I add this js and refresh, the dashboard just keeps "loading" and shows nothing. Is there any way to fix it? And by the way, how can I pass the value of a token, for example "remark" in this case, to the js? The format of js is kind of different from what I know. What kind or type of js is it? Thx in advance!

0 Karma
1 Solution

tom_frotscher
Builder

Hi,

i think your dashboard is not loading, because there is some kind of error in your js. After you opened the dashboard with the js, did you take a look in the browsers console? Is there an Error? (Most Browser have a shortcut on F12 to open the console)

To get and set the values of a token in js you can use this:

var unsubmittedTokens = mvx.Components.getInstance('default');
// get the value of a token called remark
unsubmittedTokens.get("remark");
// set the value of a token called remark to "value"
unsubmittedTokens.set("remark", "value");<code>

To make this work, you must import the mvc lib. Change this part of your code:

var deps = [
     "splunkjs/ready!",
     "splunkjs/mvc/searchmanager"
 ];
 var db_boo = true;
 var qt_boo = true;

  require(deps, function(mvc) {
...

To this:

 var deps = [
 "splunkjs/mvc",
 "splunkjs/mvc/utils",
 "splunkjs/ready!",
 "splunkjs/mvc/searchmanager"
 ];
 var db_boo = true;
 var qt_boo = true;

 require(deps, function(mvc, utils) {
...

Hope this helps,

Greetings

Tom

View solution in original post

0 Karma

tom_frotscher
Builder

Hi,

i think your dashboard is not loading, because there is some kind of error in your js. After you opened the dashboard with the js, did you take a look in the browsers console? Is there an Error? (Most Browser have a shortcut on F12 to open the console)

To get and set the values of a token in js you can use this:

var unsubmittedTokens = mvx.Components.getInstance('default');
// get the value of a token called remark
unsubmittedTokens.get("remark");
// set the value of a token called remark to "value"
unsubmittedTokens.set("remark", "value");<code>

To make this work, you must import the mvc lib. Change this part of your code:

var deps = [
     "splunkjs/ready!",
     "splunkjs/mvc/searchmanager"
 ];
 var db_boo = true;
 var qt_boo = true;

  require(deps, function(mvc) {
...

To this:

 var deps = [
 "splunkjs/mvc",
 "splunkjs/mvc/utils",
 "splunkjs/ready!",
 "splunkjs/mvc/searchmanager"
 ];
 var db_boo = true;
 var qt_boo = true;

 require(deps, function(mvc, utils) {
...

Hope this helps,

Greetings

Tom

View solution in original post

0 Karma

LuiesCui
Communicator

Thank u for ur reply! Well, I check the console and it tells me

"Uncaught TypeError: undefined is not a function
Failed to load resource: net::ERR_CACHE_MISS "
I'm not sure what it means, and when I deleted line 12 to line15 of my js, the dashboard shows up. So I think the problem should be caused by the ".on('click',funtion{" staff. Any idea to fix it?
I also tried the way to pass the token as u said. Xml code remains the same and js code shows below:

var deps = [
        "splunkjs/mvc",
        "splunkjs/mvc/utils",
        "splunkjs/ready!",
        "splunkjs/mvc/searchmanager"
    ];
    require(deps, function(mvc, utils) {
        var unsubmittedTokens = mvc.Components.getInstance('default');
        var remarkValue = unsubmittedTokens.get("remark");
        //unsubmittedTokens.set("remark", "value");    I don't wanna set its value here
        var remark = document.getElementById("Remark");
        remark.innerHTML=remarkValue
    });

Then the div shows "undefined" no matter what I click in the table. Is there anything I did wrong? Thx again!

0 Karma

tom_frotscher
Builder

Hi,

if you just want to set the initial value of the Token "remark" to an other value, this definitly works:

 var deps = [
 "jquery",
 "splunkjs/mvc",
 "splunkjs/ready!",
 "splunkjs/mvc/searchmanager"
];

require(deps, function($,mvc) {
var unsubmittedTokens = mvc.Components.getInstance('default');
    unsubmittedTokens.set("remark", "value");
});

Your code in the previews posts is a little messed up. For example you selected an html element with document.getElementById("table"); which is normal vanilla java script. Then, you tried to use table.on('click:cell', function(properties) {, but on() is a jQuery function, and therefore only works on jquery objects. To select an object with jQuery you can use $("#table")

0 Karma

LuiesCui
Communicator

Well of course I would like to set the value of the token but what I wanna do first is to pass a token from dashboard to js, then pass a related token back to dashboard. And I think the js didn't get the token cuz I tried the code above, and when I pass a token back to dashboard, it shows "value". What should I do?

0 Karma

tom_frotscher
Builder

I think this is what you want to do. Use this js:

var deps = [
"jquery",
"splunkjs/mvc",
"splunkjs/mvc/tableview",
"splunkjs/mvc/searchmanager",
"splunkjs/mvc/simplexml/ready!"
];

require(deps, function($,mvc, TableView) {
var unsubmittedTokens = mvc.Components.getInstance('default');
unsubmittedTokens.set("remark", "Initial Value");

mvc.Components.get('table').getVisualization(function(tableView) {
    tableView.on('click', function(e) {
        e.preventDefault();
        if(e.field=="solution"){
            if(e.data["row.remark"]){
                console.log("here");
                unsubmittedTokens.set("remark", e.data["row.remark"]);
            } else {
                console.log("else");
                unsubmittedTokens.set("remark", "The Remark Value was null");
            }
        };
    });
 });
 });

And to make this work, delete this part in your simple xml.

        <drilldown>
          <set token="remark">$row.remark$</set>
       </drilldown>
0 Karma

LuiesCui
Communicator

Actually i don't want to set the value of the token in js. Instead in this case, I want to get the value of the token "remark" (not the value of the column) from dashboard, in js see if its value is null or some other things, then change the value if it's null, then pass the token to the div to display.
Now the problem is, as I tried, "unsubmittedTokens.set("remark", "Initial Value");" works, which means I can set the value of tokens by js and that's great. However, on the other hand "var remarkValue = unsubmittedTokens.get("remark");" doesn't work, which means I can't get the value of token to js. This is what confuses me cuz I really wanna pass the token by this way.
And I think there are 3 events can be used in js: 1.clicking the table, 2.value changing of the token, and 3.value changing of the text of div. I don't know which one is better.
Ur code above works and I see "function(e)" and "e.preventDefault();" in ur code, what does it mean by "e"? Thank you so much!

0 Karma

tom_frotscher
Builder

The e is the Event that is cause by clicking on a table row. The preventDefault stops the standard drilldown behavior and you can define one by yourself. In this case we changed the value of the token.

This: var remarkValue = unsubmittedTokens.get("remark"); should defenitly work. Does it throw an error? Is the result empty? Or why do you think it do not work? Ofcourse it is empty at the beginning, because when you load your dashboard, the token is not set.

I do not understand why in your scenario you want to listen on the change of the token, because the token only changes when you clock on the table. Nothing else changes the token in your implementation. Ofcourse you can also listen on the change of a token:

  unsubmittedTokens.on("change:tokenName", function(model, value, options) {
    // Do whatever you want
  });
0 Karma

LuiesCui
Communicator

In fact I got a input in my dashboard:

<input type="dropdown" token="location" searchWhenChanged="true">
            <label></label>
            <default>%</default>
            <choice value="%">ALL</choice>
            <choice value="%Page%">Page</choice>
            <choice value="%Search%">Search</choice>
          </input>

I think the default value of token "location" will be "%".
Then I editd my js ( let's ignore .on('click',function) by now ) as:

var unsubmittedTokens = mvc.Components.getInstance("default");
var location = unsubmittedTokens.get("lotaciton");
unsubmittedTokens.set("remark",location);

Theoretically when the dashboard is loaded, the token "remark" should get the value of token "location", which makes the div show "%" ( I tried "unsubmittedTokens.set("remark","aaa");" and it did show "aaa" in div). But actually the div shows "$remark$". This is why I think the "unsubmittedTokens.get()" is not working. Any ideas?

0 Karma

tom_frotscher
Builder

First: there is a typo in var location = unsubmittedTokens.get("lotaciton");

Second: Why you not just do a console.log(unsubmittedTokens.get("location")) or a console.log(location) and take a look on the browsers console to see what the value is?

0 Karma

LuiesCui
Communicator

Sorry about the typo but gosh I still got "$remark$" after I corrected my code

var unsubmittedTokens = splunkjs.mvc.Components.getInstance("default");
var location = unsubmittedTokens.get("location");
console.log(unsubmittedTokens.get("location"));
unsubmittedTokens.set("remark",location);

And I stil saw "undefined" in browser console. Did I miss anyting in deps[] or parameters of the function?

0 Karma

tom_frotscher
Builder

Ok, thats odd. For me it works in Firefox, but not in Chrome 😞

Sorry, currently i do not see our misstake.

0 Karma

LuiesCui
Communicator

Yeah...tried firefox and worked. Thank you so much for this question!
Btw, can I use the same way to get/set tokens in js in the /appserver/static/components/forcedirected folder?

0 Karma

LuiesCui
Communicator

Yeah...tried firefox and workd. Well thank you so much on this qustion!

0 Karma

LuiesCui
Communicator

Here is the dashboard xml :

<dashboard script="home2.js">
  <label>solution2</label>
  <set token="remark"></set>
  <row>
    <panel>
      <input type="dropdown" token="location" searchWhenChanged="true">
        <label></label>
        <default>%</default>
        <choice value="%">ALL</choice>
        <choice value="%Page%">Page</choice>
        <choice value="%Search%">Search</choice>
      </input>
      <input type="radio" token="issue" searchWhenChanged="true">
        <label></label>
        <default>%</default>
        <choice value="%">ALL</choice>
        <search>
          <query>| inputlookup worklog.csv | where (location LIKE "$location$") | stats count by issue</query>
        </search>
        <fieldForLabel>issue</fieldForLabel>
        <fieldForValue>issue</fieldForValue>
      </input>
      <table id="table">
        <search>
          <query>| inputlookup worklog.csv | where (location LIKE "$location$")  AND (issue LIKE "$issue$") | table solution remark</query>
          <earliest>0</earliest>
          <latest></latest>
        </search>
        <option name="wrap">true</option>
        <option name="rowNumbers">false</option>
        <option name="drilldown">row</option>
        <option name="dataOverlayMode">none</option>
        <option name="count">10</option>
        <fields>solution</fields>
      </table>
    </panel>
    <panel id="chart1">
      <html>
        <div>
          <p id="Remark">$remark$</p>
        </div>  
      </html>
    </panel>
  </row>
</dashboard>

And the js:

var deps = [
    "jquery",
    "splunkjs/mvc",
    "splunkjs/mvc/utils",
    "splunkjs/ready!",
    "splunkjs/mvc/tableview",
    "splunkjs/mvc/searchmanager",
    "splunkjs/mvc/simplexml/ready!"
];

var db_boo = true;
var qt_boo = true;

require(deps, function($,mvc, TableView) {
    var unsubmittedTokens = splunkjs.mvc.Components.getInstance("default");
    var location = unsubmittedTokens.get("lotaciton");
    unsubmittedTokens.set("remark",location);

    mvc.Components.get('table').getVisualization(function(tableView) {
        tableView.on('click', function(d) {
            window.open("http://www.baidu.com");
            d.preventDefault();
            if(d.field=="solution"){
                if(d.data["row.remark"]){
                    unsubmittedTokens.set("remark", d.data["row.remark"]);
                } else {
                    unsubmittedTokens.set("remark", "");
                }
            };
        });
    });
});
0 Karma

tom_frotscher
Builder

I copied your xml and js code and for me it works. It shows a "%" when the dashboard is loaded. I guess it shows "$remark$" because of your typo here:
var location = unsubmittedTokens.get("lotaciton");

If i change the token name to your wrong type, it also shows "$remark$" for me.

0 Karma

tom_frotscher
Builder

It shows "value" because here:

unsubmittedTokens.set("remark", "value");

we set it to "value". You already interacted with the token. Maybe you can describe what exactly you want to achive in the end?

0 Karma
Did you miss .conf21 Virtual?

Good news! The event's keynotes and many of its breakout sessions are now available online, and still totally FREE!