Splunk Enterprise

js for button on table cell

willtseng0217
Explorer

Dear Splunkers , 
May I ask for help please~

I have a dashboard like below , I need someone give me some suggestion , to add a button on action fields
when button clicked, then change the status filed content to "Ack"

thank u all , 

<dashboard version="1.1" theme="dark" script="test.js">
<label>111</label>
<row>
<panel>
<table>
<search>
<query>|makeresults count=5 | eval A=random(), B=random(), status="", action="Ack/UnAck"</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
</search>
<option name="count">20</option>
<option name="dataOverlayMode">none</option>
<option name="drilldown">none</option>
<option name="percentagesRow">false</option>
<option name="rowNumbers">false</option>
<option name="totalsRow">false</option>
<option name="wrap">true</option>
</table>
</panel>
</row>
</dashboard>

Labels (3)
Tags (2)
0 Karma
1 Solution

kamlesh_vaghela
SplunkTrust
SplunkTrust

@willtseng0217 

 

Can you please try XML and js below?

XML

 

 

<dashboard version="1.1" theme="dark" script="test.js">
	<label>js for button on table cell</label>
	<row>
		<panel>
			<table id="table1">
				<search>
					<query>|makeresults count=5 | eval A=random(), B=random(), status=A, action=A</query>
					<earliest>-24h@h</earliest>
					<latest>now</latest>
					<sampleRatio>1</sampleRatio>
				</search>
				<option name="count">20</option>
				<option name="dataOverlayMode">none</option>
				<option name="drilldown">none</option>
				<option name="percentagesRow">false</option>
				<option name="rowNumbers">false</option>
				<option name="totalsRow">false</option>
				<option name="wrap">true</option>
			</table>
		</panel>
	</row>
</dashboard>

 

 

 

 

test.js

 

 

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/simplexml/ready!'
], function (_, $, mvc, TableView) {
    console.log("Hie 2");
    var CustomCellRenderer = TableView.BaseCellRenderer.extend({
        canRender: function (cell) {
            // Enable this custom cell renderer for the confirm field
            return _(["action", "status"]).contains(cell.field);
        },
        render: function ($td, cell) {
            if (cell.field == "action") {
                let unique_id = cell.value;
                let button_id = "action_btn_" + unique_id;
                let div_id = "status_div_" + unique_id;

                let button = $('<button />', {
                    value: 'Ack',
                    id: button_id,
                    on: {
                        click: function () {
                            console.log(unique_id, button_id);
                            console.log(div_id);
                            let div_value = $('#' + div_id).html();
                            if (div_value == "Ack") {
                                $('#' + div_id).html("Unack");
                                $('#' + button_id).html("Ack");

                            } else {
                                $('#' + div_id).html("Ack");
                                $('#' + button_id).html("Unack");
                            }
                        }
                    }
                }).addClass("extend_expiry btn-sm btn btn-primary").html("Ack");
                $td.html(button)
            }
            if (cell.field == "status") {
                let div_id = "status_div_" + cell.value;
                let html = `<div id="` + div_id + `"></div>`
                $td.html(html)
            }
        }
    });

    var sh = mvc.Components.get("table1");
    if (typeof (sh) != "undefined") {
        sh.getVisualization(function (tableView) {
            // Add custom cell renderer and force re-render
            tableView.table.addCellRenderer(new CustomCellRenderer());
            tableView.table.render();
        });
    }
});

 

 

 

Screenshot

Screenshot 2024-02-05 at 11.33.45 AM.png

Note: Just change the code as per your logic and feel free to ask.

 

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

willtseng0217
Explorer

@kamlesh_vaghela 

Sir, 

May I ask for a help , If I want to limit user to use this method 

Could u please teach me how tow set the least privilege

I just know that config power user and edit-kvstore , but I don't want give the normal user to much 
thanks for help

willtseng0217_0-1709170733565.png

 



🙂

0 Karma

willtseng0217
Explorer

@kamlesh_vaghela 
Sir , may I ask about add data to kv store . 
I have try example from SA-devforall post entry as below

function postNewEntry() {
    var record = {
        _time: (new Date).getTime() / 1000,
        status: $("#status").val(),
        message: $("#message").val(),
        user: Splunk.util.getConfigValue("USERNAME")
    }
    $.ajax({
        url: '/en-US/splunkd/__raw/servicesNS/nobody/SA-devforall/storage/collections/data/example_test',
        type: 'POST',
        contentType: "application/json",
        async: false,
        data: JSON.stringify(record),
        success: function(returneddata) { newkey = returneddata }
    })
}

 
and modify it to mine

    function postNewEntry(unique_id, status) {
        var record = {
            _time: (new Date).getTime() / 1000,
            status: $("#status").val(),
            unique_id:  $("#unique_id").val(),
        }

        $.ajax({
            url: ' https://10.1.1.1:8089/servicesNS/nobody/test/storage/collections/data/man_data/',
            type: 'POST',
            contentType: "application/json",
            async: false,
            data: JSON.stringify(record),
            success: function(returneddata) { newkey = returneddata }
        })
    }

always get , net::ERR_CERT_AUTHORITY_INVALID

if I do it one linux curl , and get another error code by test another kv-store file

[root@test-Splunk01 local]# curl -k -u admin:admin123 https://10.1.1.1:8089/serviceNS/nobody/test/storage/collections/data/splunk_man -H 'Content-Type: application/json' -d '{"status": "UnACK" , "unique_id" : "11305421231213"}'
<!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>405 Method Not Allowed</title></head><body><h1>Method Not Allowed</h1><p>Specified method is not allowed on this resource.</p></body></html>

what can I do now ...
btw ,  this is my transforms config ..

[root@plunk01 local]# cat transforms.conf
[man_data]
fields_list = _key , unique_id , status

[splunk_man]
collection = splunk_man
external_type = kvstore
fields_list = _key, unique_id , status



 thank u so much 

0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

Updated Answer for this thread.

@willtseng0217  Please try below full sample code below your requirement.

collections.conf

[my_status_data]
enforceTypes = true
field.status = string
field.unique_id = string

 

transforms.conf

 

[my_status_data_lookup]
external_type = kvstore
collection = my_status_data
fields_list = _key, status, unique_id

 

XML

<dashboard version="1.1" theme="dark" script="test.js">
	<label>js for button on table cell</label>
	<row>
		<panel>
			<table id="table1">
				<search id="SearchA">
					<query>| makeresults count=10 
| eval A=1
| accum A
| eval B=random()
| lookup my_status_data_lookup unique_id as A output status
| eval action= case(isnull(status),"Ack",status=="Ack","Unack", 1=1,"Ack") +"|"+ A
| eval status = if(isnull(status),"",status) +"|"+A
</query>
					<earliest>-24h@h</earliest>
					<latest>now</latest>
					<sampleRatio>1</sampleRatio>
				</search>
				<option name="count">20</option>
				<option name="dataOverlayMode">none</option>
				<option name="drilldown">none</option>
				<option name="percentagesRow">false</option>
				<option name="rowNumbers">false</option>
				<option name="totalsRow">false</option>
				<option name="wrap">true</option>
			</table>
		</panel>
	</row>
</dashboard>

 

test.js

 

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/simplexml/ready!'
], function (_, $, mvc, TableView) {
    console.log("Hie 65100");
    var SearchA = mvc.Components.get("SearchA");
    let CustomCellRenderer = TableView.BaseCellRenderer.extend({
        canRender: function (cell) {
            // Enable this custom cell renderer for the confirm field
            return _(["action", "status"]).contains(cell.field);
        },
        render: function ($td, cell) {
            if (cell.field == "action") {
                const cell_value = cell.value.split("|")[0]
                let unique_id = cell.value.split("|")[1];
                let button_id = "action_btn_" + unique_id;
                let div_id = "status_div_" + unique_id;

                console.log(cell_value);

                let button = $('<button />', {
                    value: cell_value,
                    id: button_id,
                    on: {
                        click: function () {
                            console.log(unique_id, button_id);
                            console.log(div_id);
                            let div_value = $('#' + div_id).html();
                            let new_status = "";
                            if (div_value == "Ack") {
                                $('#' + div_id).html("Unack");
                                $('#' + button_id).html("Ack");
                                new_status = "Unack"

                            } else {
                                $('#' + div_id).html("Ack");
                                $('#' + button_id).html("Unack");
                                new_status = "Ack"
                            }
                            update_collection_data(unique_id, new_status);
                        }
                    }
                }).addClass("extend_expiry btn-sm btn btn-primary").html(cell_value);
                $td.html(button)
            }
            if (cell.field == "status") {
                console.log(cell.value);
                const cell_value = cell.value.split("|")[0]
                const cell_id = cell.value.split("|")[1]
                console.log(cell_value);
                console.log(cell_id);
                let div_id = "status_div_" + cell_id;
                let html = `<div id="` + div_id + `">` + cell_value + `</div>`
                $td.html(html)
            }
        }
    });

    function update_collection_data(unique_id, status) {
        var record = {
            status: status,
            unique_id: unique_id,
            _key: unique_id
        }
        let collection = "my_status_data";
        $.ajax({
            url: '/en-US/splunkd/__raw/servicesNS/nobody/search/storage/collections/data/' + collection + '/' + unique_id,
            type: "POST",
            async: true,
            contentType: "application/json",
            data: JSON.stringify(record),
            success: function(returneddata) {
                console.log("Updated!", returneddata)
            },
            error: function(xhr, textStatus, error) {
                console.error("Error Updating!", xhr, textStatus, error);
                $.ajax({
                    url: '/en-US/splunkd/__raw/servicesNS/nobody/search/storage/collections/data/' + collection,
                    type: "POST",
                    async: true,
                    contentType: "application/json",
                    data: JSON.stringify(record),
                    success: function(returneddata) {
                        console.log("Added!", returneddata)
                    },
                    error: function(xhr, textStatus, error) {
                        console.error("Error Adding!", xhr, textStatus, error);
                    }
                });
            }
        });


    }
    let sh = mvc.Components.get("table1");
    if (typeof (sh) != "undefined") {
        sh.getVisualization(function (tableView) {
            // Add custom cell renderer and force re-render
            tableView.table.addCellRenderer(new CustomCellRenderer());
            tableView.table.render();
        });
    }
});

 

 

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.

 

 

willtseng0217
Explorer

@kamlesh_vaghela 

it's works !! 

deeply appreciated your kindly support ... 

0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

@willtseng0217 

 

Can you please try XML and js below?

XML

 

 

<dashboard version="1.1" theme="dark" script="test.js">
	<label>js for button on table cell</label>
	<row>
		<panel>
			<table id="table1">
				<search>
					<query>|makeresults count=5 | eval A=random(), B=random(), status=A, action=A</query>
					<earliest>-24h@h</earliest>
					<latest>now</latest>
					<sampleRatio>1</sampleRatio>
				</search>
				<option name="count">20</option>
				<option name="dataOverlayMode">none</option>
				<option name="drilldown">none</option>
				<option name="percentagesRow">false</option>
				<option name="rowNumbers">false</option>
				<option name="totalsRow">false</option>
				<option name="wrap">true</option>
			</table>
		</panel>
	</row>
</dashboard>

 

 

 

 

test.js

 

 

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/simplexml/ready!'
], function (_, $, mvc, TableView) {
    console.log("Hie 2");
    var CustomCellRenderer = TableView.BaseCellRenderer.extend({
        canRender: function (cell) {
            // Enable this custom cell renderer for the confirm field
            return _(["action", "status"]).contains(cell.field);
        },
        render: function ($td, cell) {
            if (cell.field == "action") {
                let unique_id = cell.value;
                let button_id = "action_btn_" + unique_id;
                let div_id = "status_div_" + unique_id;

                let button = $('<button />', {
                    value: 'Ack',
                    id: button_id,
                    on: {
                        click: function () {
                            console.log(unique_id, button_id);
                            console.log(div_id);
                            let div_value = $('#' + div_id).html();
                            if (div_value == "Ack") {
                                $('#' + div_id).html("Unack");
                                $('#' + button_id).html("Ack");

                            } else {
                                $('#' + div_id).html("Ack");
                                $('#' + button_id).html("Unack");
                            }
                        }
                    }
                }).addClass("extend_expiry btn-sm btn btn-primary").html("Ack");
                $td.html(button)
            }
            if (cell.field == "status") {
                let div_id = "status_div_" + cell.value;
                let html = `<div id="` + div_id + `"></div>`
                $td.html(html)
            }
        }
    });

    var sh = mvc.Components.get("table1");
    if (typeof (sh) != "undefined") {
        sh.getVisualization(function (tableView) {
            // Add custom cell renderer and force re-render
            tableView.table.addCellRenderer(new CustomCellRenderer());
            tableView.table.render();
        });
    }
});

 

 

 

Screenshot

Screenshot 2024-02-05 at 11.33.45 AM.png

Note: Just change the code as per your logic and feel free to ask.

 

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.

 

 

willtseng0217
Explorer

@kamlesh_vaghela 
Sir 
really thank for response so quickly

May I Know , is that possible to keep status field content when dashboard refresh ?
for example , 
when I click that button , write _time, a , b , status to the lookup table or something, 
once dashboard refresh , I can lookup that and keep this status content alive

0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

Yes @willtseng0217 

You can store data KV store. You have to just take care of a couple of things.

  1. create a lookup with a unique ID that can be used for updating records.
  2. call KVStore API with the click of a button.
  3.  display status and action button value as per the KV Store. 

 

I hope this will help you to move further 🙂 

kamlesh_vaghela
SplunkTrust
SplunkTrust
0 Karma

willtseng0217
Explorer

I would like to use the test.js to do this , try to ask for ChatGPT but can't done my job...

0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

Now you can try Chat GTP. it will give this answer only. 😜 🤣

willtseng0217
Explorer

I appreciate your help very much 😍

0 Karma
Get Updates on the Splunk Community!

Join Us for Splunk University and Get Your Bootcamp Game On!

If you know, you know! Splunk University is the vibe this summer so register today for bootcamps galore ...

.conf24 | Learning Tracks for Security, Observability, Platform, and Developers!

.conf24 is taking place at The Venetian in Las Vegas from June 11 - 14. Continue reading to learn about the ...

Announcing Scheduled Export GA for Dashboard Studio

We're excited to announce the general availability of Scheduled Export for Dashboard Studio. Starting in ...