Search code examples
rshinyradio-button

Insert/remove UI based on radioButtons() value


It's been a while since I played around with Shiny, and I want to insert a UI and remove the UI whenever I toggle between two values of radioButtons(). Ideally, I want the Z selectInput() to appear whenever the user selects TRUE from the radio button; I'd also want it to disappear whenever the user selects FALSE from the radio button. Below I have some very sad code that makes the Z input appear but not disappear.

Any advice of how to accomplish this would be greatly appreciated.

library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

  # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel for inputs ----
    sidebarPanel(

      # Radio buttons
      radioButtons("partial_val","Partial",choices = c("TRUE","FALSE"), selected = "FALSE")

    ),

    # Main panel for displaying outputs ----
    mainPanel(

      # Output: Data file ----
      tableOutput("contents")

    )

  )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

  observeEvent(input$partial_val==TRUE, {
    insertUI(
      selector = "#partial_val",
      where = "afterEnd",
      ui = selectInput('z_var', 'Z', choices = '')
    )
  })

  observeEvent(input$partial_val==FALSE, {
    removeUI(
      selector = "#z_var)"
    )
  })

  output$contents <- renderTable({

    # input$file1 will be NULL initially. After the user selects
    # and uploads a file, head of that data file by default,
    # or all rows if selected, will be shown.

    req(input$file1)

    # when reading semicolon separated files,
    # having a comma separator causes `read.csv` to error
    tryCatch(
      {
        df <- read.csv(input$file1$datapath)
      },
      error = function(e) {
        # return a safeError if a parsing error occurs
        stop(safeError(e))
      }
    )

    if(input$disp == "head") {
      return(head(df))
    }
    else {
      return(df)
    }

  })
}

# Run the application
shinyApp(ui = ui, server = server)

Solution

  • As mentioned, an option is also switching to conditionalPanel:

    library(shiny)
    
    # Define UI for application that draws a histogram
    ui <- fluidPage(
      
      # Sidebar layout with input and output definitions ----
      sidebarLayout(
        
        # Sidebar panel for inputs ----
        sidebarPanel(
          
          # Radio buttons
          radioButtons("partial_val","Partial",choices = c("TRUE","FALSE"), selected = "FALSE"),
          
          # Conditional panel
          conditionalPanel(
            condition = 'input.partial_val == "TRUE"',
            selectInput('z_var', 'Z', choices = '')
          )
          
        ),
        
        # Main panel for displaying outputs ----
        mainPanel(
          
          # Output: Data file ----
          tableOutput("contents")
          
        )
        
      )
    )
    
    # Define server logic required to draw a histogram
    server <- function(input, output) {
      
      output$contents <- renderTable({
        
        # input$file1 will be NULL initially. After the user selects
        # and uploads a file, head of that data file by default,
        # or all rows if selected, will be shown.
        
        req(input$file1)
        
        # when reading semicolon separated files,
        # having a comma separator causes `read.csv` to error
        tryCatch(
          {
            df <- read.csv(input$file1$datapath)
          },
          error = function(e) {
            # return a safeError if a parsing error occurs
            stop(safeError(e))
          }
        )
        
        if(input$disp == "head") {
          return(head(df))
        }
        else {
          return(df)
        }
        
      })
    }
    
    # Run the application
    shinyApp(ui = ui, server = server)