Search code examples
javascriptrshinyshinyjs

In Shiny click event is not working when using modules


why when Im using modules the clickable feature in my highchart treemap is not working.

I tried this without module and worked well.

Probably is something related no namespace, right , but I can not find what it it.

Any help ?

This is my code:

library(shiny)
library(highcharter)
library(gapminder)
library(shinyjs)

source(file = 'module_ex_2.R')


ui <- fluidPage(

  mod_ex2_UI('ex1')

)

server <- function(input, output){
  mod_ex2_Server('ex1')

}

shinyApp(ui, server)

My module file:

mod_ex2_UI <- function(id) {
  ns <- NS(id)
  tagList(

    highchartOutput(ns("hcontainer")),
    htmlOutput(ns("clicked"))

  )
}

mod_ex2_Server <- function(id) {
  moduleServer(
    id,
    function(input, output, session) {

      click_js <- JS("function(event) {Shiny.onInputChange('treemapclick', event.point.name);}")

      output$hcontainer <- renderHighchart({

        gapminder::gapminder %>%
          dplyr::filter(year  == 2007) %>%
          highcharter::data_to_hierarchical(group_vars = c(continent, country), size_var = pop) %>%
          hchart(type = "treemap") %>%
          hc_plotOptions(treemap = list(events = list(click = click_js)))

      })


      output$clicked <- renderUI({
        if(is.null(input$treemapclick)){
          reactable::reactable(data =gapminder::gapminder %>%
                                 dplyr::filter(year  == 2007) %>%
                                 dplyr::filter(country == 'China'))
        }else{


          reactable::reactable(data =gapminder::gapminder %>%
                                 dplyr::filter(year  == 2007) %>%
                                 dplyr::filter(country == input$treemapclick))
        }
      })

    }
  )
}

Thanks any help would be amazing.


Solution

  • You need to append the namespace to your custom event like so:

    click_js <- JS(
       glue::glue("function(event) {{
                      Shiny.setInputValue('{NS(id)('treemapclick')}',
                                          event.point.name);
                   }}"
       )
    )
    

    N.B. onInputChange is the older name for setInputValue and the latter is more verbose (cf. to this Shiny article)