Search code examples
javascriptrshinyvisnetwork

Shiny actionbutton within visnetwork node title


I am trying to imbed an action button within a visNetwork node, so that an action can be initiated by clicking on the button within the tooltip.

I can get the button to appear within the node label but no event is triggered when it is clicked. Where am I going wrong?

Minimal example:

library(shiny)  
library(visNetwork)

ui <- fluidPage(
    visNetworkOutput("net")
)

server <- function(input, output) {

    ## minimal nodes and edges example
    nodes <- data.frame(id = 1, title = HTML("<button id='test' type='button' class='btn btn-default action-button'>test</button>"))
    edges <- data.frame(from = c(1,1))

    ## render the single-node network
    output$net = renderVisNetwork(visNetwork(nodes, edges))

    ## detect when the actionbutton is clicked
    observeEvent(input$test, {
        print("clicked")
    })
}


shinyApp(ui,server)

Solution

  • Just add an onclick event to the button. There you can trigger JavaScript and use Shiny.oninputchange() to create an input$test as desired. Since input$test is only triggered if the value you send changes you should Math.random() to generate a (varying) random value.

    Reproducible example:

     library(shiny)  
     library(visNetwork)
    
     ui <- fluidPage(
         visNetworkOutput("net")
     )
    
     server <- function(input, output) {
    
      ## minimal nodes and edges example
      nodes <- data.frame(id = 1, title = HTML("<button id='test' type='button'
         class='btn btn-default action-button' onclick ='Shiny.onInputChange(\"test\", 
         Math.random());'>test</button>"))
      edges <- data.frame(from = c(1,1))
    
      ## render the single-node network
      output$net = renderVisNetwork(visNetwork(nodes, edges))
    
      ## detect when the actionbutton is clicked
      observeEvent(input$test, {
          print("clicked")
      })
    }
    
     shinyApp(ui,server)
    

    Note:

    I am not sure what you overall goal is and this comment might be unnecessary, but just a pointer that you can also bind onclick events to other objects than the action button. (Also just to the circle instead of using a popup).