1

I have a R Shiny app with many inputs, and before it runs the output, I want to avoid it showing the output until it has all required inputs. However, there are many outputs, and rather than type them all out, I'd like to use the req() call by their div tag (inputs).

Here's a simple app:

library(shiny)

ui <- fluidRow(
    column(12,
           div(id = "inputs",
        selectInput(inputId = "reasons",
                    label = "Select Your Reasons",
                    choices = c("Everything", "Your Hair", "Your Eyes", "Your Smile"),
                    multiple = TRUE),
        selectInput(inputId = "verb",
                    label = "Select Your Verb",
                    choices = c("love", "hate"),
                    multiple = TRUE)),
        textOutput("message")
    )
)

server <- function(input, output) {
    
    output$message <- renderText({
        paste("I", input$verb, input$reasons)
    })

}

shinyApp(ui = ui, server = server)

I trieded adding shiny::req(input$inputs) in between the renderText and paste calls, but that code made nothing show up, even when I selected values for the 2 dropdowns.

J.Sabree
  • 2,280
  • 19
  • 48
  • `isolate()` may help here. you could also have the message output respond to a button click via `observeEvent`. – TTS Jun 28 '21 at 17:44
  • I can think of a few ways to achieve this, but shiny modules is the one that seems to match your design. – SmokeyShakers Jun 29 '21 at 12:20
  • @SmokeyShakers, I haven't heard of shiny modules before. How would I update the above code to group them together? – J.Sabree Jun 29 '21 at 12:27

1 Answers1

0

As I mentioned, you might find modules a good fit. However, personally, I'd go with an intermediate reactive to require.

library(shiny)

ui <- fluidRow(
  column(12,
         div(id = "inputs",
             selectInput(inputId = "reasons",
                         label = "Select Your Reasons",
                         choices = c("Everything", "Your Hair", "Your Eyes", "Your Smile"),
                         multiple = TRUE),
             selectInput(inputId = "verb",
                         label = "Select Your Verb",
                         choices = c("love", "hate"),
                         multiple = TRUE)),
         textOutput("message")
  )
)

server <- function(input, output) {
  
  ## returns NULL if any of the listed inputs are null
  inputs <- reactive({
    input_list<- lapply(c('reasons','verb'), function(x) input[[x]])
    if(list(NULL) %in% input_list) NULL else input_list
  })
  
  
  output$message <- renderText({
    req(inputs())
    paste("I", input$verb, input$reasons)
  })
  
}

shinyApp(ui = ui, server = server)
SmokeyShakers
  • 3,372
  • 1
  • 7
  • 18