# Splunk Dashboard JavaScript MVC Guide ## Overview This guide explains how to properly implement JavaScript in Splunk dashboards to trigger searches and handle token values. ## 1. Basic Structure for Dashboard JavaScript ### Required Libraries ```javascript require([ 'underscore', 'jquery', 'splunkjs/mvc', 'splunkjs/mvc/searchmanager', 'splunkjs/mvc/simplexml/ready!' ], function( _, $, mvc, SearchManager ) { // Your code here }); ``` ### Important: Wait for Dashboard Ready The `splunkjs/mvc/simplexml/ready!` module ensures the dashboard is fully loaded before your code runs. ## 2. Accessing MVC Components ### Get Dashboard Tokens ```javascript // Get default token model var tokens = mvc.Components.get("default"); // Get submitted token model var submittedTokens = mvc.Components.get("submitted"); // Get a specific token value var tokenValue = tokens.get("mytoken"); // Set a token value tokens.set("mytoken", "new_value"); ``` ### Get Dashboard Elements ```javascript // Get a search manager by ID var searchManager = mvc.Components.get("my_search"); // Get a visualization by ID var chart = mvc.Components.get("my_chart"); // Get an input by ID var dropdown = mvc.Components.get("my_dropdown"); ``` ## 3. Creating and Executing Searches Programmatically ### Create a New Search ```javascript var mySearch = new SearchManager({ id: "my_programmatic_search", search: "index=socradar_incidents | stats count", earliest_time: "-24h@h", latest_time: "now", preview: true, cache: false, autostart: false // Don't start automatically }); // Start the search mySearch.startSearch(); ``` ### Create a Search with Token Values ```javascript // Using mvc.tokenSafe for token-aware searches var mySearch = new SearchManager({ id: "update_status_search", search: mvc.tokenSafe("| sendalert update_socradar_incident_status param.incident_id=$incident_id$ param.new_status=$new_status$"), earliest_time: "-1m", latest_time: "now", autostart: false }); // Token values will be automatically resolved when the search runs ``` ## 4. Handling Search Results ### Listen for Search Events ```javascript mySearch.on('search:done', function(properties) { console.log("Search completed!"); // Get the results var results = mySearch.data("results"); results.on("data", function() { var data = results.data(); console.log("Results:", data); // Process results if (data && data.rows && data.rows.length > 0) { // Handle successful results alert("Status updated successfully!"); } }); }); mySearch.on('search:error', function(properties) { console.error("Search error:", properties.content.messages); }); mySearch.on('search:fail', function(properties) { console.error("Search failed:", properties.content.messages); }); ``` ## 5. Complete Example: Button Click Handler ### HTML Button (in dashboard XML) ```xml ``` ### JavaScript Implementation ```javascript require([ 'underscore', 'jquery', 'splunkjs/mvc', 'splunkjs/mvc/searchmanager', 'splunkjs/mvc/simplexml/ready!' ], function( _, $, mvc, SearchManager ) { // Get token models var tokens = mvc.Components.get("default"); var submittedTokens = mvc.Components.get("submitted"); // Button click handler $("#update_status_btn").on("click", function() { // Get token values var incidentId = tokens.get("incident_id"); var newStatus = tokens.get("new_status"); // Validate inputs if (!incidentId || !newStatus) { alert("Please select an incident and status"); return; } // Create search to update status var updateSearch = new SearchManager({ id: "update_status_search_" + Date.now(), // Unique ID search: "| sendalert update_socradar_incident_status param.incident_id=\"" + incidentId + "\" param.new_status=\"" + newStatus + "\"", earliest_time: "-1m", latest_time: "now", autostart: false }); // Handle search completion updateSearch.on('search:done', function(properties) { console.log("Status update completed"); // Refresh the main search to show updated data var mainSearch = mvc.Components.get("incident_details_search"); if (mainSearch) { mainSearch.startSearch(); } alert("Status updated successfully!"); }); // Handle search errors updateSearch.on('search:error search:fail', function(properties) { console.error("Status update failed:", properties); alert("Failed to update status. Please try again."); }); // Start the search updateSearch.startSearch(); }); }); ``` ## 6. Best Practices ### 1. Always Wait for Dashboard Ready ```javascript require(['splunkjs/mvc/simplexml/ready!'], function() { // Dashboard is ready }); ``` ### 2. Use Token-Safe Strings ```javascript // Good - tokens will be resolved search: mvc.tokenSafe("index=main sourcetype=$sourcetype$") // Bad - tokens won't be resolved search: "index=main sourcetype=$sourcetype$" ``` ### 3. Unique Search Manager IDs ```javascript // Add timestamp to ensure uniqueness id: "my_search_" + Date.now() ``` ### 4. Clean Up Search Managers ```javascript // Dispose of search when done updateSearch.on('search:done', function() { updateSearch.finalize(); }); ``` ### 5. Handle Token Changes ```javascript // Listen for token changes tokens.on("change:mytoken", function(model, value) { console.log("Token changed:", value); // React to token change }); ``` ## 7. Common Patterns ### Execute Search on Token Change ```javascript tokens.on("change:incident_id", function(model, value) { if (value) { var detailSearch = new SearchManager({ id: "incident_detail_" + Date.now(), search: "index=socradar_incidents alarm_id=\"" + value + "\" | head 1", autostart: true }); } }); ``` ### Conditional Search Execution ```javascript $("#run_search_btn").click(function() { var searchType = tokens.get("search_type"); var searchQuery; switch(searchType) { case "high_risk": searchQuery = "index=socradar_incidents alarm_risk_level=HIGH"; break; case "recent": searchQuery = "index=socradar_incidents | head 100"; break; default: searchQuery = "index=socradar_incidents"; } var search = new SearchManager({ id: "conditional_search_" + Date.now(), search: searchQuery, autostart: true }); }); ``` ## 8. Debugging Tips ### 1. Check if Components Exist ```javascript var component = mvc.Components.get("my_component"); if (component) { console.log("Component found:", component); } else { console.error("Component not found!"); } ``` ### 2. List All Components ```javascript console.log("All components:", mvc.Components.toJSON()); ``` ### 3. Debug Token Values ```javascript console.log("All tokens:", tokens.toJSON()); console.log("Submitted tokens:", submittedTokens.toJSON()); ``` ### 4. Monitor Search Progress ```javascript mySearch.on('all', function(eventName) { console.log("Search event:", eventName); }); ``` ## Example: Complete Status Update Implementation ```javascript require([ 'underscore', 'jquery', 'splunkjs/mvc', 'splunkjs/mvc/searchmanager', 'splunkjs/mvc/simplexml/ready!' ], function(_, $, mvc, SearchManager) { console.log("Dashboard JavaScript loaded"); // Get token models var tokens = mvc.Components.get("default"); var submittedTokens = mvc.Components.get("submitted"); // Debug: List all components console.log("Available components:", Object.keys(mvc.Components.toJSON())); // Set up button click handler $(document).on("click", "#update_status_btn", function(e) { e.preventDefault(); // Get current token values var incidentId = tokens.get("incident_id"); var newStatus = tokens.get("new_status"); console.log("Updating incident:", incidentId, "to status:", newStatus); if (!incidentId || !newStatus) { alert("Please select an incident and a new status"); return; } // Disable button during update var $btn = $(this); $btn.prop('disabled', true).text('Updating...'); // Create the update search var updateSearch = new SearchManager({ id: "status_update_" + Date.now(), search: '| sendalert update_socradar_incident_status param.incident_id="' + incidentId + '" param.new_status="' + newStatus + '"', earliest_time: "-1m", latest_time: "now", cache: false, autostart: true }); // Handle completion updateSearch.on('search:done', function() { console.log("Status update successful"); // Re-enable button $btn.prop('disabled', false).text('Update Status'); // Show success message alert("Status updated successfully!"); // Refresh the incidents table var tableSearch = mvc.Components.get("incident_details_table_search"); if (tableSearch) { tableSearch.startSearch(); } // Clean up updateSearch.finalize(); }); // Handle errors updateSearch.on('search:error search:fail', function(state, job) { console.error("Status update failed:", state); // Re-enable button $btn.prop('disabled', false).text('Update Status'); // Show error message alert("Failed to update status. Please check the logs."); // Clean up updateSearch.finalize(); }); }); // Monitor token changes for debugging tokens.on("change", function() { console.log("Token changed:", tokens.toJSON()); }); }); ``` This guide provides the foundation for implementing JavaScript in Splunk dashboards with proper MVC integration, token handling, and search execution.