Reputation: 159
I'm designing a Shiny app to analyse survey results, and I want users to be able to select a question either from a selectInput
dropdown ("Jump to selection") or by clicking actionButtons
("Previous", "Next"). These articles were a helpful starting point:
https://shiny.rstudio.com/reference/shiny/1.0.4/reactiveVal.html
https://shiny.rstudio.com/articles/action-buttons.html
My problem is that selectInput
clashes with the results of the actionButtons
, since both are controlling the same object. How do I get them to work together? I don't want to use isolate()
with selectInput
and make users click an additional button; I would like the selection to change as soon as they select it. Thanks!
library(shiny)
ui <- fluidPage(
mainPanel(
actionButton("previous_q",
"Previous"),
actionButton("next_q",
"Next"),
selectInput("jump",
"Jump to Question",
choices = 1:10),
textOutput("selected")
)
)
server <- function(input, output) {
# Select based on "Previous" and "Next" buttons -------
selected <- reactiveVal(1)
observeEvent(input$previous_q, {
newSelection <- selected() - 1
selected(newSelection)
})
observeEvent(input$next_q, {
newSelection <- selected() + 1
selected(newSelection)
})
# Jump to selection (COMMENTED OUT SO APP DOESN'T CRASH) ----------------
#observeEvent(input$jump, {
#newSelection <- input$jump
#selected(newSelection)
#})
# Display selected
output$selected <- renderText({
paste(selected())
})
}
shinyApp(ui = ui, server = server)
Upvotes: 3
Views: 1028
Reputation: 33530
Welcome to SO!
@StéphaneLaurent was a little faster - I'll post my solution anyway: as he already mentions you'll need as.integer(input$jump)
Furthermore you don't need the reactiveVal()
"selected". This also takes care about limiting your choices:
library(shiny)
selectInputChoices = 1:10
ui <- fluidPage(mainPanel(
actionButton("previous_q",
"Previous"),
actionButton("next_q",
"Next"),
selectInput(
"jump",
"Jump to Question",
choices = selectInputChoices,
selected = 1
),
textOutput("selected")
))
server <- function(input, output, session) {
# Select based on "Previous" and "Next" buttons -------
observeEvent(input$previous_q, {
req(input$jump)
if (as.integer(input$jump) > min(selectInputChoices)) {
newSelection <- as.integer(input$jump) - 1
updateSelectInput(session, inputId = "jump", selected = newSelection)
}
})
observeEvent(input$next_q, {
req(input$jump)
if (as.integer(input$jump) < max(selectInputChoices)) {
newSelection <- as.integer(input$jump) + 1
updateSelectInput(session, inputId = "jump", selected = newSelection)
}
})
# Display selected
output$selected <- renderText({
req(input$jump)
paste(input$jump)
})
}
shinyApp(ui = ui, server = server)
Upvotes: 1
Reputation: 84679
The problem is that input$jump
is a character string, not a number. Do:
observeEvent(input$jump, {
newSelection <- as.integer(input$jump)
selected(newSelection)
})
Upvotes: 1