Wait for an object to be rendered before adding a JS event listener?

Hi! Thanks for taking a look at this. Reproducing this problem requires the development version of visNetwork devtools::install_github("datastorm-open/visNetwork"), but maybe you know how to fix this without running the repex.

I would like to trigger an event when a button inside of a visNetwork widget is pressed. However, adding an event listener after the document loads does not work.

I suspect that this is because that button is not rendered after $document.ready().

At the bottom of this post is a reprex with (1) a simple button, as a positive control/test, and (2) a visNetwork widget.

Problem explanation

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:


So, in the reprex below, I add an event listener to that id:

    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:




ui <- fluidPage(
      type = "text/javascript",
      $(document).ready(function() {
      // Positive control: an alert for a button
        function() {
            alert("Here is an alert!");
      // This is what I am having trouble with
        function() {
          alert("Thanks for saving!")
  actionButton("clickme", "Click me for an alert!"),

server <- function(input, output, session) {
  output$mygraph <- renderVisNetwork(
      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)
1 Like

After waiting a day, I went ahead and cross-posted on StackOverflow here: https://stackoverflow.com/questions/62794827/r-shiny-run-js-after-htmlwidget-renders

Stéphane Laurent gave a fantastic answer (as usual) on the StackOverflow post, if anyone else is interested:

Basically you can just set an event listener on the HTML body:

$("body").on("click", "#editedge-saveButton", 
  function() {
    alert("Thanks for saving!")

Or you can use the super-handy htmlwidgets::onRender() function.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.