I have tried to use insertUI
as an alternative for explicitly using module UI in the UI part of Shiny app, but without the success. How should I use insertUI
in my example to get the desired effect, i.e. to be able to display modalDialog
?
This doesn't work (using insertUI
instead of explicitly using module in UI
part of app):
library(shiny)
library(magrittr)
modUI <- function(id) {
ns <- NS(id)
key_pressed <- ns("key_pressed")
js <- glue::glue_safe('
document.addEventListener("keydown", function(e) {{
Shiny.setInputValue("{key_pressed}", e.key, {{priority: "event"}});
}});
')
singleton(tags$script(htmltools::HTML(js)))
}
modServer <- function(keyEvent = "F1",
id) {
insertUI("head", "beforeEnd", modUI("test"), immediate = TRUE)
moduleServer(
id,
function(input, output, session) {
observe({
req(input$key_pressed == keyEvent)
showModal(modalDialog())
}) %>%
bindEvent(input$key_pressed)
}
)
}
ui <- fluidPage(
#modUI("test")
)
server <- function(input, output, session) {
modServer(id = "test")
}
shinyApp(ui, server)
This works (using module explicitly in the UI
part of app):
library(shiny)
library(magrittr)
modUI <- function(id) {
ns <- NS(id)
key_pressed <- ns("key_pressed")
js <- glue::glue_safe('
document.addEventListener("keydown", function(e) {{
Shiny.setInputValue("{key_pressed}", e.key, {{priority: "event"}});
}});
')
singleton(tags$script(htmltools::HTML(js)))
}
modServer <- function(keyEvent = "F1",
id) {
#insertUI("head", "beforeEnd", modUI("test"), immediate = TRUE)
moduleServer(
id,
function(input, output, session) {
observe({
req(input$key_pressed == keyEvent)
showModal(modalDialog())
}) %>%
bindEvent(input$key_pressed)
}
)
}
ui <- fluidPage(
modUI("test")
)
server <- function(input, output, session) {
modServer(id = "test")
}
shinyApp(ui, server)
The code above adds JS code to add keydown listener - modalDialog
will be displayed after pressing F1
.
CodePudding user response:
A search in the Shiny GitHub repository reveals that this is an open issue with Shiny: inserted script
tags aren't executed unless wrapped in tags$head()
. So, meanwhile, you could wrap the script tag in your module UI in tags$head()
to get this to work:
script <- tags$script(htmltools::HTML(js))
singleton(tags$head(script))