R语言 闪亮的应用程序:如何去一个步骤/条目回来(与返回按钮)后,多个数据输入/系列的单选按钮输入

bzzcjhmw  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(83)

bounty还有4天到期。回答此问题可获得+100声望奖励。ava希望引起更多关注此问题。

我已经写了一个闪亮的应用程序,向用户呈现不同的单选按钮。根据输入的不同,数字将被添加到一个score/counter,其他单选按钮将弹出(而前一个将被禁用)。
我现在想知道,我如何实现一个“后退”按钮,让用户后退一步(例如,在误点击的情况下),这意味着:
1.隐藏最近的单选按钮
1.再次激活最后一个单选按钮
1.调整score/counter
我学习了how to add a "reset" button that calls session$reload(),它删除了所有内容,用户可以重新开始。但是,如果用户可以只后退一步,那就好多了。
我发现了类似的问题(Create general purpose "go back" button in shinyhttps://www.collinberke.com/blog/posts/2021-09-12-shiny-implementing-a-next-and-back-button/index.html),但是,这些问题处理的设置略有不同。
示例:
ui.R

ui <- fluidPage(
  
  shinyjs::useShinyjs(),
  # Add an invisible counter to store the total score
  verbatimTextOutput(outputId = "counter", placeholder = TRUE),
  
  # Add a radio button with two choices
  radioButtons(inputId = "a",
               # label = "a",
               label = "a",
               choices = c("10", "5"),
               selected = ""),
  
  
  # UI elements for the b and c radio buttons
  uiOutput("b"),
  uiOutput("c"),
  uiOutput("d"),
  uiOutput("c1"),
  uiOutput("e"),
  uiOutput("f"),
  
  # Add a back button to allow the user to go back to the previous question
  actionButton(
    inputId = "reset_button",
    label = "Reset",
    width = "50%"
  ),
  textOutput("reset_val")
  
)

服务器.R

server <- function(input, output, session) {
  
  reset_rv <- reactiveVal(value = 0L)
  
  
  
  # Initialize the counter to 0
  counter <- reactiveValues(value = 0)
  
  # Track the selected options
  selected_options <- reactiveValues(
    a = NULL,
    b = NULL,
    d = NULL,
    c = NULL,
    e = NULL,
    f = NULL
  )
  
  # Update the counter when the a radio button is clicked
  observeEvent(input$a, {
    if (!is.null(input$a)) {
      selected_options$a <- input$a
      if (input$a == "5") {
        counter$value <- counter$value + 0
        output$b <- renderUI({
          radioButtons(inputId = "b",
                       label = "b",
                       choices = c("a", "10"),
                       selected = "")
        })
        
      } else if (input$a == "10") {
        counter$value <- counter$value + 8
        output$c <- renderUI({
          radioButtons(inputId = "c",
                       label = "c",
                       choices = c("L", "R"),
                       selected = "")
        })
    
        
        }}
    shinyjs::disable("a")
    })

  

# 2 -----------------------------------------------------------------------

  observeEvent(input$b, { 
    if (!is.null(input$b)) {
      selected_options$b <- input$b
      if (input$b == "5") {
        counter$value <- counter$value + 0
        output$d <- renderUI({
          radioButtons(inputId = "d",
                       label = "d",
                       choices = c("5", "10"),
                       selected = "")
        })
      } else if (input$b == "10") {
        counter$value <- counter$value + 6
        output$c1 <- renderUI({
          radioButtons(inputId = "c1",
                       label = "c",
                       choices = c("L", "R"),
                       selected = "")})}}
    shinyjs::disable("a")
    shinyjs::disable("b")
    })
  
    
  
  observeEvent(input$c, {
    if (!is.null(input$c)) {
      selected_options$c <- input$c
      if (input$c == "R") {
        counter$value <- counter$value + 0
        output$e <- renderUI({
          radioButtons(inputId = "e",
                       label = "e",
                       choices = c("5", "10"),
                       selected = "")
        })
      } else if (input$c == "L") {
        counter$value <- counter$value + 4
        output$f <- renderUI({
          radioButtons(inputId = "f",
                       label = "L",
                       choices = c("5", "10"),
                       selected = "")})}}
    
    shinyjs::disable("a")
    shinyjs::disable("c")
    })    
  
  
  
  # Update the counter output
  output$counter <- renderText({
    paste("Score:", counter$value)
  })
  
  observeEvent(input$reset_button, {
    reset_rv(input$reset_button)
    session$reload()
  })
  

  
}

快跑

shinyApp(ui = ui, server = server)
3b6akqbq

3b6akqbq1#

我建议(几乎总是)放弃renderUI并使用updateXXX函数(updateRadioButtons),因为重新呈现元素比更新现有元素慢。
此外,您可以利用radioButtons 'choiceNames/choiceValues结构来避免冗长的if子句。
要隐藏我正在使用conditionalPanels的元素:

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  verbatimTextOutput(outputId = "counter_text", placeholder = TRUE),
  radioButtons(inputId = "a",
               label = "a",
               selected = "",
               choiceNames  = c("10", "5"),
               choiceValues = c(8L, 0L)),
  conditionalPanel("input.a == 0", style = "display: none;",
                   radioButtons(inputId = "b",
                                label = "b",
                                selected = "",
                                choiceNames  = c("a", "10"),
                                choiceValues = c(0L, 6L))),
  conditionalPanel("input.a == 8", style = "display: none;",
                   radioButtons(inputId = "c",
                                label = "c",
                                selected = "",
                                choiceNames  = c("L", "R"),
                                choiceValues = c(4L, 0L))),
  conditionalPanel("input.b == 6", style = "display: none;",
                   radioButtons(inputId = "c1",
                                label = "c",
                                selected = "",
                                choiceNames = c("L", "R"),
                                choiceValues = c(0L, 0L))),
  conditionalPanel("input.b == 0", style = "display: none;",
                   radioButtons(inputId = "d",
                                label = "d",
                                selected = "",
                                choiceNames = c("5", "10"),
                                choiceValues = c(0L, 0L))),
  conditionalPanel("input.c == 0", style = "display: none;",
                   radioButtons(inputId = "e",
                                label = "e",
                                selected = "",
                                choiceNames = c("5", "10"),
                                choiceValues = c(0L, 0L))),
  conditionalPanel("input.c == 4", style = "display: none;",
                   radioButtons(inputId = "f",
                                label = "L",
                                selected = "",
                                choiceNames = c("5", "10"),
                                choiceValues = c(0L, 0L))),
  actionButton(
    inputId = "undo_button",
    label = "Undo",
    width = "25%",
    icon = icon("rotate-left")
  ),
  actionButton(
    inputId = "reset_button",
    label = "Reset",
    width = "25%",
    icon = icon("xmark")
  ),
  textOutput("reset_val")
  
)

server <- function(input, output, session) {
  radioButtonIds <- list("a", "b", "c", "c1", "d", "e", "f")
  counter <- reactive({
    # disable input after a selection was made
    lapply(radioButtonIds, function(inputId){if(isTruthy(input[[inputId]])){disable(inputId)}})
    # sum up all inputs (irrelevant inputs are set to 0)
    sum(unlist(lapply(radioButtonIds, function(inputId){as.integer(input[[inputId]])})))
  })
  observeEvent(input$undo_button, {
    # reset inputs in their hierarchical order the first check (has an entry been made?) is done on the lowest level
    if(isTruthy(input$c1) || isTruthy(input$d) || isTruthy(input$e) || isTruthy(input$f)){
      lapply(list("c1", "d", "e", "f"), function(inputId){
        updateRadioButtons(session, inputId, selected = character(0))
        enable(inputId)
      })
    } else if(isTruthy(input$b) || isTruthy(input$c)){
      lapply(list("b", "c"), function(inputId){
        updateRadioButtons(session, inputId, selected = character(0))
        enable(inputId)
      })
    } else if(isTruthy(input$a)){
      updateRadioButtons(session, inputId = "a", selected = character(0))
      enable("a")
    }
  })
  observeEvent(input$reset_button, {
    # reset all inputs independent of the hierarchy
    lapply(radioButtonIds, function(inputId){
      updateRadioButtons(session, inputId, selected = character(0))
      enable(inputId)
    })
  })
  output$counter_text <- renderText({
    paste("Score:", counter())
  })
}

shinyApp(ui = ui, server = server)

PS:在这个上下文中,你可能想检查库(shinyglide)。

相关问题