Nautica
Nautica

Reputation: 2018

How to have items in selectInput use a common numericInput?

Sample script:

library(shiny)

ui <- fluidPage(
    selectInput("Select1","Name", c("Jack", "Daisy", "Mason")),
    numericInput("num_balls", "Number of Balls", value = NA, step = 1))

server <- function(input, output,session) {
    observeEvent(input$Select1,{
        updateNumericInput(session, 'num_balls', label = "Number of Balls", value = NA, step = 1)
    }) 
}

shinyApp(ui = ui, server = server)

I have a selectInput with three names - I would like for them to share a common numericInput box and for the value to be different for each option, say for e.g. Jack gets 3 balls, Daisy gets 4 balls, Mason gets 5, however I don't know what the correct syntax would be for this to work. I would like to be able to use the values I give for each option from Select1 in some other hypothetical part of the server script.

I've tried borrowing syntax for similar questions when searching for "dependent inputs" as my search expression, as seen here for example, which recommend using some form of observe_ or creating the UI in the server script through renderUI() but I'm still not sure of the best way to create a numericInput which can serve multiple options from another input. As you can see in the example when I try and assign a number to a person, say Jack, then go to Daisy or Mason, then go back to Jack, the figure I entered disappears. I know this is because the value in updateNumericInput() is always assigned to NA.

Upvotes: 1

Views: 37

Answers (2)

Max Feinberg
Max Feinberg

Reputation: 840

You can make changes to the selectInput cause the numericInput to update like so.

library(shiny)

ui <- fluidPage(
  selectInput(inputId = "Select1",
              label = "Name",
              choices = c("Jack", "Daisy", "Mason"),
              selected = "Jack"),
  numericInput("num_balls", "Number of Balls", value = NA, step = 1))

server <- function(input, output,session) {
  observeEvent(input$Select1,{
    
    if(input$Select1 == "Jack") {
      updateNumericInput(session, 'num_balls', label = "Number of Balls", value = 3, step = 1)  
    } else if(input$Select1 == "Daisy") {
      updateNumericInput(session, 'num_balls', label = "Number of Balls", value = 4, step = 1)  
    }  else if(input$Select1 == "Mason") {
      updateNumericInput(session, 'num_balls', label = "Number of Balls", value = 5, step = 1)  
    }
  }) 
}

shinyApp(ui = ui, server = server)

However, the user can still modify the numeric input to other values if they use the numeric input box directly.

Upvotes: 1

starja
starja

Reputation: 10365

You can store the values for the balls as a reactive value and then access these values with the selected name input$Select1. To correctly store the number of balls, you need a second observer that stores the value when it was changed:

library(shiny)

ui <- fluidPage(
  selectInput("Select1","Name", c("Jack", "Daisy", "Mason")),
  numericInput("num_balls", "Number of Balls", value = NA, step = 1))

server <- function(input, output,session) {
  number_of_balls <- reactiveValues()
  number_of_balls[["Jack"]] <- NA
  number_of_balls[["Daisy"]] <- NA
  number_of_balls[["Mason"]] <- NA
  
  observeEvent(input$num_balls, {
    number_of_balls[[input$Select1]] <- input$num_balls
  })
  observeEvent(input$Select1,{
    updateNumericInput(session, 'num_balls',
                       label = "Number of Balls",
                       value = number_of_balls[[input$Select1]], step = 1)
  }) 
}

shinyApp(ui = ui, server = server)

Note: you need to initialise the reactive values with NA, otherwise the first selected value is shown as the default for the other names when nothing has been selected yet.

Upvotes: 1

Related Questions