I am trying to use visEvents()
selectNode and deselectNode arguments from the visNetwork R package to run a javascript code that would collapse/uncollapse a Shiny box (within fluidRow) based on selected/deselected nodes. The approach is inspired from the following post.
Currently the code runs without errors but the box is not (un)collapsing.
Here is a reproducible code:
library(shiny)
library(visNetwork)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(title = "Test visEvents Javascript"),
dashboardSidebar(width = 220),
dashboardBody(useShinyjs(),
tags$head(
tags$script(src = "custom.js")), # loading custom javascript functions
fluidRow(box(id = "network",
title = "Network",
status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
visNetworkOutput('network'))),
# This box should collapse/uncollapse when node is selected/deselected
fluidRow(box(id = "collapse",
title = "Collapse",
status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
collapsed = TRUE)),
))
server <- function(input, output, session) {
getDiagramPlot <- function(nodes, edges){
v <- visNetwork(
nodes,
edges
) %>%
visPhysics(stabilization = TRUE, enabled = TRUE) %>%
visOptions(highlightNearest = list(enabled = T, degree = 1, hover = F), autoResize = TRUE, collapse = FALSE) %>%
visEdges(color = list(highlight = "red")) %>% # The colour of the edge linking nodes
visLayout(improvedLayout = TRUE) %>%
visEdges(arrows = edges$arrows) %>%
visInteraction(multiselect = F) %>%
visEvents(selectNode = shinyjs::runjs("openBox('collapse')"),
deselectNode = shinyjs::runjs("closeBox('collapse')"))
return(v)
}
nodes <- data.frame(id = 1:3, label = 1:3)
edges <- data.frame(from = c(1,2), to = c(1,3))
output$network <- renderVisNetwork(
getDiagramPlot(nodes, edges)
)
}
shinyApp(ui, server)
content of the external custom.js
file:
closeBox = function(boxid) {
var box = $('#' + boxid).closest('.box');
if (!box.hasClass('collapsed-box')) {
box.find('[data-widget=collapse]').click();
}
};
openBox = function(boxid) {
var box = $('#' + boxid).closest('.box');
if (box.hasClass('collapsed-box')) {
box.find('[data-widget=collapse]').click();
}
};
I tried replacing
visEvents(selectNode = shinyjs::runjs("openBox('collapse')"),
deselectNode = shinyjs::runjs("closeBox('collapse')"))
by
visEvents(selectNode = "openBox('groupedbars')",
deselectNode = "closeBox('groupedbars')")
but it still doesn't work.
Here is the solution, in case someone may be interested:
You don’t need shinyjs::runjs()
in your visEvent()
call. Just define a js function as a text string:
visEvents(selectNode = "function(){openBox('collapse')}",
deselectNode = "function(){closeBox('collapse')}")
If you do not create a function, it will instead only call openBox()
and closeBox()
at the start when the JS interpreter pass through your file (so it gets triggered when you are trying to define it).