2

I'm looking for a way to stop update*Input functions from invalidating reactive values in my Shiny app. I want the update function to change only the visual UI component, not the underlying reactive value.

Here's a reprex:

library(shiny)

ui <- fluidPage(

    sliderInput("slide1", "Slider", min = 0, max = 10, value = 5),
    sliderInput("slide2", "Slider2", min = 0, max = 10, value = 0),
    
    textOutput("slide2_val")
)

server <- function(input, output, session) {
    
    observe({
        updateSliderInput(session, "slide2", value = input$slide1)
    }) |> 
        bindEvent(input$slide1)
    
    output$slide2_val <- renderText({
        paste("Value of `slide2`:", input$slide2)
    })
}

shinyApp(ui, server)

The desired behaviour is for the value of input$slide2 to only change when the user interacts with slide2, but for the slider UI element to change when either slide1 or slide2 are interacted with.

Importantly, this needs to work for a variety of input* functions. Listening for click events won't work for inputs like selectInput (see my related issue).

Will Hipson
  • 366
  • 2
  • 9

1 Answers1

2

In my recent answer to another question I made a suspendForNextFlush() function to temporarily stop changes to an input from being sent to Shiny. That function could be used to solve your problem, too.

I’ve gone ahead and put the function in an experimental shinysuspend package. You can install it from GitHub with:

remotes::install_github("mikmart/shinysuspend")

Then include useShinysuspend() in the UI, and call suspendForNextFlush() when updating slide2 from the server:

library(shiny)
library(shinysuspend)

ui <- fluidPage(
  useShinysuspend(),
  sliderInput("slide1", "Slider 1", min = 0, max = 10, value = 5),
  sliderInput("slide2", "Slider 2", min = 0, max = 10, value = 0),
  textOutput("slide2_val")
)

server <- function(input, output, session) {
  observe({
    suspendForNextFlush("slide2")
    updateSliderInput(session, "slide2", value = input$slide1)
  })
  
  output$slide2_val <- renderText({
    paste("Value of `slide2`:", input$slide2)
  })
}

shinyApp(ui, server)
Mikko Marttila
  • 10,972
  • 18
  • 31