Tsingis
Tsingis

Reputation: 525

How to add conditional rows which consist of few user inputs in Shiny app

I would like to show in UI only the first row (currently fluidRow) with device, color and linetype if user chooses number one, two first rows if user chooses number two and so on.

How do I add this kind of condition. I tried conditionalPanel but I failed there.

Tried to make a minimal reproducible example:

library(shiny)

shinyApp(
  ui <- fluidPage(
    fluidRow(
      column(2, offset = 1,
             selectInput(inputId = "number",
                         label = "Number:",
                         choices = list(
                           "One data set" = "1",
                           "Two data sets" = "2",
                           "Three data sets" = "3"))
      )
    ),
    fluidRow(
      column(2,
             selectInput(inputId = "dev1",
                         label = "Device:",
                         choices = list("Device 1", "Device 2"))
      ),
      column(2,
             selectInput(inputId = "col1",
                         label = "Color:",
                         choices = list("black", "red", "blue"))

      ),
      column(2,
             selectInput(inputId = "lty1",
                         label = "Linetype:",
                         choices = list("solid", "dashed"))
      )
    ),
    fluidRow(
      column(2,
             selectInput(inputId = "dev2",
                         label = "Device:",
                         choices = list("Device 1", "Device 2"))
      ),
      column(2,
             selectInput(inputId = "col2",
                         label = "Color:",
                         choices = list("black", "red", "blue"))

      ),
      column(2,
             selectInput(inputId = "lty3",
                         label = "Linetype:",
                         choices = list("solid", "dashed"))
      )
    )
  ),
  server <- function(input, output) {})

Tell me if this needs more clarifying.

Upvotes: 0

Views: 477

Answers (1)

PeterS
PeterS

Reputation: 136

solution using server side logic, client side (JS) is also an option however this seems more natural given the platform in R and also it offers more control.

library(shiny)
library(shinyFiles)
shinyApp(
  ui = fluidPage(
    fluidRow(
      column(2, offset = 1,
             selectInput(inputId = "number",
                         label = "Number:",
                         choices = list(
                           "One data set" = "1",
                           "Two data sets" = "2",
                           "Three data sets" = "3"))
      )
    ),
    uiOutput('dynamic_selections')
  ),
  server = function(input, output) {
    observeEvent(input$number,{
      output$dynamic_selections = renderUI({
        lapply(1:as.integer(input$number),function(i){
          fluidRow(
            column(2,
                   selectInput(inputId = sprintf("dev%s",i),
                               label = "Device:",
                               choices = list("Device 1", "Device 2"))
            ),
            column(2,
                   selectInput(inputId = sprintf("col%s",i),
                               label = "Color:",
                               choices = list("black", "red", "blue"))

            ),
            column(2,
                   selectInput(inputId = sprintf("lty%s",i),
                               label = "Linetype:",
                               choices = list("solid", "dashed"))
            ),
            column(2,
                   shinyFilesButton(id=sprintf("file%s",i), label='File:',title = 'Select File',multiple=FALSE, buttonType = "default", class = NULL)
            )
          )
        })
      })
      lapply(1:as.integer(input$number),function(i){
        shinyFileChoose(input, sprintf("file%s",i), roots=c(wd='.'), filetypes=c('', 'txt'))
      })
    })
  })

EDIT: it has been highlighted that in some scenarios the file chooser box is not populated. Two things could go wrong

  1. JS cannot read date attribute of folder/file therefore array is populated with null and errors when trying string split:

    var mTime = data.files.mtime[i].split('-')

    as a temp solution this can be avoided using restrictions parameter to exclude problematic folders/files?

  2. When shinyFilesButton() is rendered via renderUI and server logic then fileChooser fails to populate but without any JS error, needs to be investigated further

Upvotes: 2

Related Questions