Search code examples
rshinyreactable

How can i tell my modalDialog to be automatic closed when an input changes (eg. a tab changes)?


I have this Shiny App with a navbarPage and two tabPanels. In the first tab i have an actionLink which initializes a modalDialog including a reactable with cells as buttons. When i click on a button from the table i want to change the input from my navbarPage, i.e. change the tabPanel from "tabone" to "tabtwo". Simultaneously i want the modalDialog to be closed when the tabPanel changed. How can i tell my modalDialog to be closed then?

library(Shiny)
library(reactable)

ui = fluidPage(
  
  navbarPage(title = "tabs", id = "nav",
             
  tabPanel(title = "tabone",
           actionLink(inputId = "action", "open modalbox")),
  
  tabPanel(title = "tabtwo")
  
))

server = function(input, output, session){
  
  shinyInput = function(FUN, len, id, labels, ...) {
    inputs = character(len)
    for (i in seq_len(len)) {
      inputs[i] = as.character(FUN(paste0(id, i), label = labels[i], ...))
    }
    inputs
  }
  
 observeEvent(input$action, {
   showModal(
     modalDialog(
       tagList(reactableOutput(outputId = "table"))
     ))})
  
  output$table = renderReactable({
    data = tibble(c = "click to change navbar input") %>%
      mutate(c = shinyInput(actionButton, n(), 'id', labels = c, onclick = "Shiny.setInputValue('change', this.innerText)")) %>%
      reactable(data = .,
              sortable = FALSE,
              columns = list(
                `c` = colDef(
                  html = TRUE)
              ))})
    
  observeEvent(input$change, {
  updateTabsetPanel(session = session, inputId = "nav", selected = "tabtwo")
  })  
  
   
}

shinyApp(ui, server)

Solution

  • You can add removeModal() in observeEvent of change button.

    library(shiny)
    library(reactable)
    
    ui = fluidPage(
      
      navbarPage(title = "tabs", id = "nav",
                 
                 tabPanel(title = "tabone",
                          actionLink(inputId = "action", "open modalbox")),
                 
                 tabPanel(title = "tabtwo")
                 
      ))
    
    server = function(input, output, session){
      
      shinyInput = function(FUN, len, id, labels, ...) {
        inputs = character(len)
        for (i in seq_len(len)) {
          inputs[i] = as.character(FUN(paste0(id, i), label = labels[i], ...))
        }
        inputs
      }
      
      observeEvent(input$action, {
        showModal(
          modalDialog(
            tagList(reactableOutput(outputId = "table"))
          ))
        })
      
      output$table = renderReactable({
        data = tibble(c = "click to change navbar input") %>%
          mutate(c = shinyInput(actionButton, n(), 'id', labels = c, onclick = "Shiny.setInputValue('change', this.innerText)")) %>%
          reactable(data = .,
                    sortable = FALSE,
                    columns = list(
                      `c` = colDef(
                        html = TRUE)
                    ))})
      
      observeEvent(input$change, {
        updateTabsetPanel(session = session, inputId = "nav", selected = "tabtwo")
        removeModal()
      })  
      
      
    }
    
    shinyApp(ui, server)
    

    enter image description here