Search code examples
rshinyserver

R + Shiny + conditionalPanel: combining condition on UI and server side


I am struggling to get this done: I want to display a button in the sidebar of a shiny application (called "download aggregated data") if and only if two conditions are met, namely

(1) I select the "yes" value from the menu under "Show extra button" and

(2) The data selected and shown in the table has at least 20 rows.

Condition (2) is the consequence of selecting "large_chunk" in the "select data chunk" menu, but I want the condition to be based on the output and not on the input. In the real-life app which I am developing I will not know beforehand how many data rows I will select with my filters.

Right now only condition (1) is implemented.

I found something useful here about conditionalPanel and a condition on the server side

Shiny - conditionalPanel - set condition as output from server

but I did not get very far. Any help is appreciated!

library(shiny)
library(shinyWidgets)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(DT)
#> 
#> Attaching package: 'DT'
#> The following objects are masked from 'package:shiny':
#> 
#>     dataTableOutput, renderDataTable


df <- tibble(x=1:30, y=51:80, z=c(rep("small_chunk", 7), rep("large_chunk", 23)))


ui <- fluidPage(

  sidebarLayout(
         sidebarPanel(
            pickerInput("my_selection","Select data chunk",
                        choices=c("large_chunk", "small_chunk"),
                        selected="small_chunk",
                options = list(`actions-box` = TRUE,`selected-text-format` = "count > 3"),multiple = F),

            pickerInput("show","Show Extra Button",
                        choices=c("yes", "no"),
                        selected="yes",
                        options = list(`actions-box` = TRUE,`selected-text-format` = "count > 3"),multiple = F),

            
   conditionalPanel(
        condition = "input.show == 'yes' ",
            downloadButton("downloadData","Download aggregated data" ))
       
   ),

            
    

      mainPanel(

          DTOutput("table")
      )
 )            
     )


server <- function(input, output) {

    data_reactive <- reactive({

        df %>% filter(z %in% input$my_selection )
            

        
    })

    output$table <- renderDT({datatable(data_reactive())})

    
}





shinyApp(ui = ui, server = server)
#> PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
Shiny applications not supported in static R Markdown documents

Created on 2021-09-22 by the reprex package (v2.0.1)


Solution

  • You can do

    output[["largeChunk"]] <- reactive({
      nrow(data_reactive()) >= 20
    })
    outputOptions(output, "largeChunk", suspendWhenHidden = FALSE)
    

    and in the UI:

    conditionalPanel(
      condition = "input.show == 'yes' && output.largeChunk",
      ......