Home > OS >  Hide and Show Download Button Using Shiny Modularity
Hide and Show Download Button Using Shiny Modularity

Time:08-25

So far I made a Shiny app that has three inputs connected to the database and a final download button. Everything works well except the download button. The actual data downloading part works but I want to add one last logic that hides the download button if myvars$input3 is empty:

observe({
   if (is.null(myvars$var3)) {shinyjs::hide("???")}
   else {shinyjs::show("???")}
  })
  • server_tab2.R:

    • Function1 dropdownTab2Server:

      • Defined the date range logic with id daterange_tab2
      • Defined the last input dropdown logic with id var_list_tab2
    • Function2 downloadTab2Server:

      • Defined the logic for download button
  • server.R: (This part is not working)

    • Want to only show the download button if the third input (myvars$input3) is not empty
  • ui_tab2.R: Defined the three inputs explained in ui.R:

    • var_lab_tab2: A static dropdown input with only two choices Choice1 and Choice2

    • daterange_tab2_ui: A date range

    • subid_dropdown_tab2_ui: The last dropdown input that depends on the first two

##### server_tab2.R
#### Function 1 - A dropdown input dependent on the date range
dropdownTab2Server <- function(id) {
  moduleServer(id, function(input, output, session) {
    
    ns <- session$ns 
    rv <- reactiveValues()
    
    output$daterange_tab2_ui <- renderUI({
      req(input$var_lab_tab2) 
      dateRangeInput(ns("daterange_tab2"), "Date Range:", start = min_max_date_df$min_date, end = min_max_date_df$max_date) # Retrieved from "global.R"
    })
    
    unique_lists_tab2 <- reactive({
      sql <- glue_sql("
      SELECT
        DISTINCT list AS unique_list
      FROM table1
      WHERE date BETWEEN date ({dateid1_tab2*}) AND date ({dateid2_tab2*})
",
                      dateid1_tab2 = input$daterange_tab2[1],
                      dateid2_tab2 = input$daterange_tab2[2],
                      .con = pool
      )
      dbGetQuery(pool, sql) 
    })
    
    output$subid_dropdown_tab2_ui <- renderUI({
      req(input$daterange_tab2[1], input$daterange_tab2[2])
      
      shinyWidgets::pickerInput(
        ns("var_list_tab2"),
        "Stations:",
        choices = unique_lists_tab2(),
        multiple = T
      )
    })
    
    observe({
      rv$var1 <- input$daterange_tab2[1]
      rv$var2 <- input$daterange_tab2[2]
      rv$var3 <- input$var_list_tab2
    })
    
    return(rv)
    
  }
  )
}


#### Function 2 - download button
downloadTab2Server <- function(id, df, filename) { 
  moduleServer(id, function(input, output, session) {
    output$downloadbttn_tab2 <- downloadHandler(
      filename = function() { 
        paste0(filename, ".xlsx")
      },
      
      content = function(file) {
        WriteXLS::WriteXLS(df, file) 
      }
    )
    }
    )
}


##### server.R => Struggling with this part
function(input, output, session) {
  dropdownTab2Server("dropdown_ui_tab2") 
  
  myvars <- dropdownTab2Server("dropdown_ui_tab2") 
  
  ### download button layout => Struggling with this part
  observe({
    if (is.null(myvars$var3)) {shinyjs::hide("???")}
    else {shinyjs::show("???")}
  })
  
  downloadTab2Server(
    id = "download_ui_tab2", 
    df = fake_data(), # reactive
    filename = "data"
    )
}


##### ui_tab2.R
downloadTab2UI <- function(id) {
  ns <- NS(id) 
  
  tagList(
    shinyWidgets::pickerInput(
      ns("var_lab_tab2"),
      
      "ID:",
      choices = c("Choice1", "Choice2"), multiple = T
      ),
    
    uiOutput(ns("daterange_tab2_ui")),
    
    uiOutput(ns("subid_dropdown_tab2_ui")),
    
    downloadButton(ns("downloadbttn_tab2"), "Download Data")
  )
}


##### ui.R
downloadTab2UI("download_ui_tab2")

CodePudding user response:

You could the following in the main server part (I've changed it to an observeEvent because I think it's easier to reason what exactly it listens to):

observeEvent(myvars$var3, {
  if (is.null(myvars$var3)) {shinyjs::hide("download_ui_tab2-downloadbttn_tab2")}
  else {shinyjs::show("download_ui_tab2-downloadbttn_tab2")}
}, ignoreNULL = FALSE)

You need to prefix the download button id with the correct namespace, in your case "download_ui_tab2".

However, this is not great style as you need to manually handle the namespace. A cleaner solution would be to pass myvars to the downloadTab2Server module as an argument and then have the observeEvent in the module code. Then you can directly use downloadbttn_tab2 and don't need to manually prefix the namespace.

  • Related