0
votes

I would like to update the value of numericInput from selectInput and vice versa. I would like for the selectInput to change to "Other" as selected when any value is manually entered in numericInput. I would also like for the numericInput to update when "A","B" or "C" is selected from select input. I know that it's best to avoid circular references but I was wondering if this is doable. Here's what I have so far. The numeric input flashes briefly when "A", "B" or "C" is selected but it changes back to empty and the selected value changes back to other.

library(shiny)

if (interactive()) {
  ui <- fluidPage(
    selectInput(
      "controller",
      NULL,
      c(
        "A" = 35000,
        "B" = 1200,
        "C" = 12231,
        "Other"
      ),selected = "Other"
    ),
    numericInput("inNumber", "Input number", 0)
  )
  
  server <- function(input, output, session) {
    observeEvent(input$controller, {
      x <- input$controller
      updateNumericInput(session, "inNumber", value = x)
    })
    
    observeEvent(input$inNumber,{
        updateSelectInput(session,"controller",selected ="Other")
    })
  }
  
  shinyApp(ui, server)
}

Thanks

2

2 Answers

1
votes

It seems to me that there is an unexpected reset of the numeric input with @starja's solution. Here is another solution:

ui <- fluidPage(
  selectInput(
    "controller",
    NULL,
    c(
      "A" = 35000,
      "B" = 1200,
      "C" = 12231,
      "Other"
    ), selected = "Other"
  ),
  numericInput("inNumber", "Input number", 0)
)

server <- function(input, output, session) {
  
  flags <- reactiveValues(a=FALSE, b=FALSE)
  
  observeEvent(input$inNumber, {
    if(flags$a) flags$a <- FALSE
  }, ignoreInit = TRUE, priority = 0)
  
  observeEvent(input$inNumber, {
    if(!flags$a && input$controller != "Other"){
      updateSelectInput(session, "controller", selected = "Other")
      flags$a <- flags$b <- TRUE
    }
  }, ignoreInit = TRUE, priority = 1)
  
  observeEvent(input$controller, {
    if(flags$b) flags$b <- FALSE
  }, ignoreInit = TRUE, priority = 0)
  
  observeEvent(input$controller, {
    if(!flags$b){
      updateNumericInput(session, "inNumber", value=input$controller)
      flags$a <- flags$b <- TRUE
    }
  }, ignoreInit = TRUE, priority = 1)
  
}

shinyApp(ui, server)
1
votes

Your problem is that the change from "Other" to "A/B/C" automatically triggers the second observer, but the first time it shouldn't be triggered because this is a change you want to display. You can use a flag for the first change to circumvent this problem. But it doesn't feel really nice, maybe there are better options.

library(shiny)

if (interactive()) {
  ui <- fluidPage(
    selectInput(
      "controller",
      NULL,
      c(
        "A" = 35000,
        "B" = 1200,
        "C" = 12231,
        "Other"
      ),selected = "Other"
    ),
    numericInput("inNumber", "Input number", 0)
  )
  
  server <- function(input, output, session) {
    
    first_change <- FALSE
    
    observeEvent(input$controller, {
      x <- input$controller
      updateNumericInput(session, "inNumber", value = x)
      first_change <<- TRUE
      
    })
    
    observeEvent(input$inNumber,{
      if (!(input$controller == "Other" || first_change)) {
      updateSelectInput(session,"controller",selected ="Other")
      }
      first_change <<- FALSE
      
    })
  }
  
  shinyApp(ui, server)
}