4
votes

in the R shiny script below, I am trying to make the functionality such that in the first submenuItem, every selectInput values depend upon the item selection in the previous column. Data is attached and the code is also written. However I am not able to achieve the desired result. Kindly run the code and check, I want the entire server logic to come under one function only. Thanks and please help.

library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(

  id = "tabs",
  menuItem("Charts", icon = icon("bar-chart-o"),
           menuSubItem("Sub-item 1", tabName = "subitem1"),
           menuSubItem("Sub-item 2", tabName = "subitem2")
  ))),
dashboardBody(
tabItems(tabItem("subitem1", uiOutput("brand_selector")),
         tabItem("subitem2", 4))
))
server <- shinyServer(function(input, output) {
candyData <- read.table(
text = "
Brand       Candy           value
Nestle      100Grand        Choc1
Netle       Butterfinger    Choc2
Nestle      Crunch          Choc2
Hershey's   KitKat          Choc4
Hershey's   Reeses          Choc3
Hershey's   Mounds          Choc2
Mars        Snickers        Choc5
Nestle      100Grand        Choc3
Nestle      Crunch          Choc4
Hershey's   KitKat          Choc5
Hershey's   Reeses          Choc2
Hershey's   Mounds          Choc1
Mars        Twix            Choc3
Mars        Vaid            Choc2",
header = TRUE,
stringsAsFactors = FALSE)
output$brand_selector <- renderUI({
box(title = "Data", status = "primary", solidHeader = T, width = 12,
    fluidPage(
      fluidRow(
        Brand_Select <- unique(candyData$Brand),
        column(2,offset = 0, style='padding:1px;', 
selectInput("Select1","select1",Brand_Select)),
        Candy_Select <- candyData$Candy[candyData$Brand == input$Select1],
        Candy_Select <- unique(Candy_Select),
        column(2,offset = 0, style='padding:1px;', 
selectInput("Select2","select2",Candy_Select)),
        Value_Select <- candyData$value[candyData$Candy == input$Select2],
column(2, offset = 0, 
style='padding:1px;',selectInput("select3","select3",Value_Select ))
)))
})
})
shinyApp(ui = ui, server = server)

Capture

1

1 Answers

5
votes

Your code does not work because every time one of the inputs changes, the entire renderUI runs again, thereby resetting all your inputs since they are all created from scratch again!

So how can we work around this? You could try something like the following. Note that I stripped a lot of the unnecessary formatting so it is a bit easier to see how this works.

We create the inputs in the UI, and add some observeEvents that listen to changes in the first or second input. If the first input changes, this fires the first observeEvent and will change the choices of input$Select2. Subsequently, this will trigger the second observeEvent, thereby limiting the choices in input$Select3.

I hope this helps!

library(shiny)
library(shinydashboard)

candyData <- read.table(
  text = "
    Brand       Candy           value
    Nestle      100Grand        Choc1
    Netle       Butterfinger    Choc2
    Nestle      Crunch          Choc2
    Hershey's   KitKat          Choc4
    Hershey's   Reeses          Choc3
    Hershey's   Mounds          Choc2
    Mars        Snickers        Choc5
    Nestle      100Grand        Choc3
    Nestle      Crunch          Choc4
    Hershey's   KitKat          Choc5
    Hershey's   Reeses          Choc2
    Hershey's   Mounds          Choc1
    Mars        Twix            Choc3
    Mars        Vaid            Choc2",
  header = TRUE,
  stringsAsFactors = FALSE)

ui <- fluidPage(
  selectInput("Select1","select1",unique(candyData$Brand)),
  selectInput("Select2","select2",choices = NULL),
  selectInput("Select3","select3",choices=NULL ))

server <- function(input, output,session) {
 observeEvent(input$Select1,{
   updateSelectInput(session,'Select2',
           choices=unique(candyData$Candy[candyData$Brand==input$Select1]))
 }) 
  observeEvent(input$Select2,{
    updateSelectInput(session,'Select3',
           choices=unique(candyData$value[candyData$Brand==input$Select1 & candyData$Candy==input$Select2]))
  }) 

}

shinyApp(ui = ui, server = server)