Reputation: 158
I want to pass to Shiny ID of an element of specific pseudo-class when it is clicked. Everything is working fine if UI elements are created in UI part of Shiny app. But when UI is created on server side (by renderUI
) it doesn't work. Below is reproducible example.
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
fluidRow(
tags$div(id = "ui1", class = 'shiny-html-output shiny-bound-output',
tags$a(id = "ID1", class = "my-class", href = "#", 'Link 1')
),
uiOutput("ui2")
)
)
server <- function(input, output) {
output$ui2 <- renderUI({
tags$a(id = "ID2", class = "my-class", href = "#", 'Link 2')
})
shinyjs::runjs(
'$(document).ready(function(){
$(".my-class").click(function(){
alert($(this).attr("id"));
});
});')
}
shinyApp(ui, server)
Upvotes: 5
Views: 764
Reputation: 1118
$(document).ready
approach won't work because server will not render it outputs until the DOM is ready. Use session$onFlushed
instead, with once
parameter set to TRUE
, then shiny will run the function only once, not on every session flush.
This will work:
library(shiny)
library(shinyjs)
script <- "$('.my-class').click(function(){
alert($(this).attr('id'));
});"
ui <- fluidPage(
useShinyjs(),
fluidRow(
tags$div(id = "ui1", class = 'shiny-html-output shiny-bound-output',
tags$a(id = "ID1", class = "my-class", href = "#", 'Link 1')
),
uiOutput("ui2")
)
)
server <- function(input, output, session) {
output$ui2 <- renderUI({
tags$a(id = "ID2", class = "my-class", href = "#", 'Link 2')
})
session$onFlushed(function() {
shinyjs::runjs(script)
}, once=TRUE)
}
shinyApp(ui, server)
Upvotes: 2