How to branch processing using picker input

Viewed 75

I am currently developing a Shiny app. I would like to use multiple Picker Inputs to branch the processing flow. Specifically, I would like to build the processing flow shown in the figure below.

enter image description here

For example When Option1 is selected in PickerInput1 → PickerInput2 displays the vector of Middle Class. → Set the Multiple option of PickerInput2 to False to make it a single selection. → Turn off Numeric Input so that you cannot enter numbers. (Make it gray out or hide it on the UI in the first place) → Press the button to display "expression1".

When Option2 is selected in PickerInput1 → PickerInput2 displays the vector of Middle Class. → Set the Multiple option of PickerInput2 to False to make it a single selection. → Turn on Numeric Input so that you cannot enter numbers. → Press the button to display "expression1".

When Option3 is selected in PickerInput1 → PickerInput2 displays the vector of Middle Class and Major Class. → Set the Multiple option of PickerInput2 to True to select multiple options. → Turn off Numeric Input so that you cannot enter numbers. → Press the button to display "expression2".

When Option4 is selected in PickerInput1 → PickerInput2 displays the MajorClass vector. → Set the Multiple option of PickerInput2 to True to select multiple options. → Turn off Numeric Input so that you cannot enter numbers. → Press the button to display "expression2".

Is it possible to branch the processing flow in this way? I especially want to hear ・ Is it possible to change the Mutiple settings? (Maybe I will use updatePickerInput, but can I change it with that function?) ・ Can Numeric Input be switched ON / OFF?

The sample code is below.

library("shiny")
library("shinyWidgets")

major_class <- c("A1","A2","A3")
middle_class <- c("A1_1","A1_2","A2_1","A2_2","A3_1","A3_2")


ui <- fluidPage(

  fluidRow(
    column(
      width = 2, offset = 1,
      pickerInput(
        inputId = "p1",
        label = "PickerInput1",
        choices = c("Option1","Option2","Option3","Option4"),
        options = list(
          `live-Search` = TRUE,
          `actions-box` = TRUE,
          size = 7,
          `selected-text-format` = "count > 3"
        ),
        multiple =FALSE
      )
    ),
    column(
      width = 2,
      pickerInput(
        inputId = "p2",
        label = "PickerInput2",
        choices = "",
        options = list(
          `live-Search` = TRUE,
          `actions-box` = TRUE,
          size = 7,
          `selected-text-format` = "count > 3"
        ),
        multiple =TRUE
      ),
      numericInput("num", label = "Numeric input", value = 1)
    ),
    column(
      width = 2,
      actionButton("p3","finish")
      
      ),
    textOutput("resule_message")
      )
    )

  

server <- function(input, output, session) {

  observeEvent(input$p1 ,{
    
    if(input$p1 %in% c("Option1","Option2")){
      updatePickerInput(session = session, inputId = "p2",
                      choices = middle_class)
    }
    
    if(input$p1 %in% c("Option3")){
      updatePickerInput(session = session, inputId = "p2",
                        choices = list(major = major_class,
                                       middle = middle_class))
    }
    if(input$p1 %in% c("Option4")){
      updatePickerInput(session = session, inputId = "p2",
                        choices = major_class)
    }
    
    })
  
  observeEvent(input$p3 ,{
    
    if(input$p1 %in% c("Option1")){
      output$resule_message <- renderText({
        paste0("expression1")
      })
    }
    else{
      output$resule_message <- renderText({
        paste0("expression2")
      })
      
    }
  })

  
}

shinyApp(ui = ui, server = server)


Those who can solve this problem, those who know how to change the processing flow depending on the input conditions of PikcerInput, If you know that you can do something similar using another method, please let me know.

1 Answers

One way to do it is to use renderUI for your second pickerInput and display it based on your conditions. Try this

library("shiny")
library("shinyWidgets")

major_class <- c("A1","A2","A3")
middle_class <- c("A1_1","A1_2","A2_1","A2_2","A3_1","A3_2")


ui <- fluidPage(
  
  fluidRow(
    column(
      width = 2, offset = 1,
      pickerInput(
        inputId = "p1",
        label = "PickerInput1",
        choices = c("Option1","Option2","Option3","Option4"),
        options = list(
          `live-Search` = TRUE,
          `actions-box` = TRUE,
          size = 7,
          `selected-text-format` = "count > 3"
        ),
        multiple =FALSE
      )
    ),
    column(
      width = 2, uiOutput("pickr2"), uiOutput("numinput")
    ),
    column(
      width = 2,
      actionButton("p3","finish")
      
    ),
    textOutput("resule_message")
  )
)


server <- function(input, output, session) {
  
  output$pickr2 <- renderUI({
    req(input$p1)
    if(input$p1 %in% c("Option1","Option2")){
      choices <- middle_class
      TORF <- FALSE
    }else{
      TORF <- TRUE
      if(input$p1 %in% c("Option3")){
        choices <- c(middle_class,major_class)
      }else choices <- major_class
    }
    pickerInput(
      inputId = "p2",
      label = "PickerInput2",
      choices = choices,
      options = list(
        `live-Search` = TRUE,
        `actions-box` = TRUE,
        size = 7,
        `selected-text-format` = "count > 3"
      ),
      multiple =TORF
    )
    
  })
  
  output$numinput <- renderUI({
    req(input$p1)
    if(input$p1 %in% c("Option2")){
      numericInput("num", label = "Numeric input", value = 1)
    }else return(NULL)
    
  })
  
  observeEvent(input$p3 ,{
    req(input$p1)
    if(input$p1 %in% c("Option1")){
      output$resule_message <- renderText({
        paste0("expression1")
      })
    }else{
      output$resule_message <- renderText({
        paste0("expression2")
      })
      
    }
  })
  
}

shinyApp(ui = ui, server = server)
Related