Reputation: 526
I have a shiny app with a bunch of numeric inputs. Some of them are dependent on the value of others. As an example, let's say that I need input_1 to be changed if the entered input_2 is greater, such that input_1 = input_2 + 1. The problem is that if the user inputs their value too slowly, it takes the first digit of the entered input_2, for instance 5, and makes the input_1 equal to 6, even if you finish typing 540.
Here's an example:
library(shiny)
ui <- fluidPage(
numericInput("input1", "Input 1:", 0),
numericInput("input2", "Input 2:", 0)
)
server <- function(input, output, session) {
observeEvent(input$input2, {
if (input$input2 > input$input1) {
updateNumericInput(session, "input1", value = input$input2 + 1)
}
})
}
shinyApp(ui, server)
I have tried using invalidateLater, or debounce, but I believe I haven't done it correctly since the output still changes almost immediately. Ideally it would only update once focus is lost, but I don't want to add js to my code. So having a fixed timer to update seems like a good middle ground. Any ideas?
Upvotes: 1
Views: 135
Reputation: 526
Here's an example using the delay
function from the shinyjs
package:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(), # call for shinyjs to be used in the ui part of the dashboard
numericInput("value1",
"Value 1:",
value = 40),
numericInput("value2",
"Value 2:",
value = 50)
)
server <- function(input, output, session) {
observeEvent(input$value1, {
if (input$value1 > input$value2) {
delay(2000, # the delay in milliseconds that is imposed
updateNumericInput(session = session, "value2", value = input$value1 + 1))
}
})
}
shinyApp(ui, server)
In the event that value1 should be greater than value2, after 2 sec., value2 will be updated to be equal to 1 + value1.
Upvotes: 1
Reputation: 33530
As you have already mentioned debounce
is the right way to go:
library(shiny)
ui <- fluidPage(
numericInput("input1", "Input 1:", 0),
numericInput("input2", "Input 2:", 0)
)
server <- function(input, output, session) {
input2_d <- debounce(reactive({input$input2}), 1000L)
observeEvent(input2_d(), {
if (input2_d() > input$input1) {
updateNumericInput(session, "input1", value = input2_d() + 1)
}
})
}
shinyApp(ui, server)
Upvotes: 1