community.rstudio cross-post here
I am working with an HTML widget from the development version of visNetwork.
I would like to set an event listener on one of the buttons in that widget. However, just adding that event listener in $(document).ready(function()
doesn't work because the button does not exist until after the Shiny server renders the widget output.
I'll add three sections below with my attempted solutions, a reprex, and a more detailed explanation of my problem. Thanks! :)
Attempted Solution
I've tried defining a setEventListener
function (in a string), and then running js$startEventListener
in the server. Then the question is: where in the server would I put that?
It would need to run right after the visNetwork render function (renderVisNetwork). If I put it in renderVisNetwork
, it runs too soon (the button doesn't exist until right after renderVisNetwork
finishes running). I tried making a dummy input value that renderVisNetwork
increments (and then using observeEvent
to run js$startEventListener
each time renderVisNetwork
terminates), but that somehow put me in an infinite loop, and seemed a bit hacky anyways.
I also thought this google groups post might help, but I tried the session$onFlushed
solution and it didn't have any effect.
Reprex
library(shiny)
library(visNetwork)
# Note: requires devel visNetwork. `devtools::install_github("datastorm-open/visNetwork")`
ui <- fluidPage(
tags$head(
tags$script(
type = "text/javascript",
'
$(document).ready(function() {
// Positive control: an alert for a button
$("#clickme").click(
function() {
alert("Here is an alert!");
});
// This is what I am having trouble with
$("#editedge-saveButton").click(
function() {
alert("Thanks for saving!")
});
})
'
)
),
actionButton("clickme", "Click me for an alert!"),
visNetworkOutput("mygraph")
)
server <- function(input, output, session) {
output$mygraph <- renderVisNetwork(
visNetwork(
nodes = data.frame(id = "A", label = "A"),
edges = data.frame(to = "A", from = "A", label = "A to A")
) %>%
visOptions(manipulation = list(
enabled = TRUE,
editEdgeCols = c("label")
))
)
}
shinyApp(ui, server)
More details
In visNetwork, you can "edit" an edge, like so:
I want to call a function whenever the user presses the "save" button.
That button has an id:
I can try to add an event listener to that id like so:
$("#editedge-saveButton").click(
function() {
alert("Thanks for saving!")
});
But it doesn't work, even though a similar event listener for a test button does work:
Note that, if I add that event listener in the console after I load the app, it works just fine:
This meshes with my idea that there's nothing wrong with my event listener code, it's just that the visNetwork widget doesn't exist at the time that the main JS code is executed.