繁体   English   中英

通过insertUI重置动态生成的小部件的输入字段

[英]Reset input fields of dynamically generated widgets through insertUI

我正在尝试开发Shinkapp,这是更大形式的一部分。 特别是,对于此模块,用户可以动态添加(通过insertUI)和删除(通过removeUI)具有与上一个控件完全相同的新行。 此外,每个新的小部件都将包含与上一行小部件完全相同的选择,这要归功于Eli Berkow ,他找到了最后一种功能的解决方案。

理想情况下,在用户提交答案后,将shinyjs放置在observeEvent()中的shinyjs包的reset()函数来重置每个字段的输入。 这与“静态”窗口小部件(此示例中未包括)很好用,但是我找不到一种方法来重置动态生成的窗口小部件的输入字段。

我试图将每一行分配给不同的div()并在我的observeEvent()内部使用了for循环来重置每个div()内部的输入,但是只清理了一些字段。 此外,理想情况下,如果该按钮不仅可以重置字段,还可以删除用户添加的每一行并从0开始重新计算,那将是更好的选择。下面有一些代码在UI中插入了“ 重置按钮” ,但仍然没有任何功能。


library(shiny)
library(shinyjs)

###= UI
ui <- fluidPage(

  br(),

  useShinyjs(),

  br(),

  fluidRow(
    column(width = 3,
           align = "center",
           h5("Letters")
    ),
    column(width = 3,
           align = "center",
           h5("Numbers")
    )
  ),

  br(),

  fluidRow(
    column(width = 12,
           tags$div(id = "amr_test_placeholder")
    )
  ),

  fluidRow(

    br(),
    # "+" and "-" buttons
    column(width = 12,
           actionButton(inputId = "add_amr_test",
                        label = icon(name = "plus",
                                     lib = "font-awesome")),
           actionButton(inputId = "remove_amr_test",
                        label = icon(name = "times",
                                     lib = "font-awesome")),
           actionButton(inputId = "reset_button",
                        label = "RESET FIELDS")
    )
  ),

  br(),
  br(),

  fluidRow(
    column(width = 6,
           tableOutput(outputId = "show_table")
    )
  )

)

###= SERVER
server <- function(input, output, session) {

  observe({

    toggleState(id = "remove_amr_test",
                condition = input$add_amr_test >= input$remove_amr_test)

  })



  amr_test_values <- reactiveValues(val = 0,
                                    ignore = 0)


  ### Defined the input number to count every row
  input_number <- reactive({

    input_number <- input$add_amr_test - input$remove_amr_test + 1

    return(input_number)

  })




  observeEvent(input$add_amr_test, {

    amr_test_divId <- length(amr_test_values$val) + 1

    ###= Animal species
    if (!is.null(eval(parse(text = paste0("input$letters_", input_number() - 1))))) {

      letters_value = eval(parse(text = paste0("input$letters_", input_number() - 1)))

    } else {

      letters_value = ""

    }

    ###= Animal sample type
    if (!is.null(eval(parse(text = paste0("input$numbers_", input_number() - 1))))) {

      numbers_value = eval(parse(text = paste0("input$numbers_", input_number() - 1)))

    } else {

      numbers_value = ""

    }

    ###= Insert dynamic UI
    insertUI(
      selector = "#amr_test_placeholder",
      where = "beforeBegin",
      ui = tags$div(id = amr_test_divId,
                    tags$head(tags$style(HTML(".shiny-split-layout > div {overflow: visible;}"))),

                    br(),

                    fluidRow(
                      column(width = 3,
                             splitLayout(cellWidths = c("18%", "82%"),
                                         h5(paste0(input_number(), ". ")),
                                         selectizeInput(inputId = paste0("letters_",
                                                                         input_number()),
                                                        label =  NULL,
                                                        choices = c("A" = "",
                                                                    "A",
                                                                    "B",
                                                                    "C",
                                                                    "D",
                                                                    "E",
                                                                    "F",
                                                                    "F"),
                                                        selected = letters_value,
                                                        width = "100%",
                                                        options = list(create = TRUE))
                             )
                      ),
                      column(width = 3,
                             selectizeInput(inputId = paste0("numbers_",
                                                             input_number()),
                                            label = NULL,
                                            choices = list("1" = "",
                                                           "1" = "1",
                                                           "2" = "2",
                                                           "3" = "3",
                                                           "4" = "4",
                                                           "5" = "5"),
                                            selected = numbers_value,
                                            width = "100%")
                      )
                    )
      )
    )

    amr_test_values$val <- c(amr_test_values$val,
                             amr_test_divId)

  }, ignoreNULL = FALSE)

  ###= Remove dynamic UI
  observeEvent(input$remove_amr_test, {

    removeUI(

      selector = paste0('#', amr_test_values$val[length(amr_test_values$val)])

    )

    amr_test_values$val <- amr_test_values$val[-length(amr_test_values$val)]

  })






  ###= Dataset to check the dynamic updates of the responses
  response <- reactive({

    if (input_number() != 0) {

      response <- data.frame("Letters" = sapply(X = 1:input_number(),
                                                FUN = function(i) {

                                                  input[[paste0("letters_", i)]]

                                                }),
                             "Numbers" = sapply(X = 1:input_number(),
                                                FUN = function(i) {

                                                  input[[paste0("numbers_", i)]]

                                                })

      )

      return(response)

    } else {

      response <- NULL

    }

  })



  output$show_table <- renderTable({

    response()

  })

}



###= Launch App
shinyApp(ui = ui, server = server)

可以在以下链接中看到预期的结果。

谢谢!

编辑:

Eli Berkow对我先前版本问题的回答非常有效,因此我将其标记为正确。

我已经更新了代码,以了解当应用程序启动时自动显示小部件的第一行时,Eli的脚本应如何工作。 我不知道是否要修改与reactValues或最后一个watchEvent相关的内容。 因此,在此版本的脚本中,我添加了自动显示第一行的功能。 什么将适应Eli的代码?

ps:我在小部件下添加了一个反应性数据集,以实际查看值的存储方式是否正确(只需检查一下以了解脚本是否可以正常工作)。

谢谢!

见下文:

library(shiny)
library(shinyjs)

###= UI
ui <- fluidPage(

    br(),

    useShinyjs(),

    br(),

    fluidRow(
        column(width = 3,
               align = "center",
               h5("Letters")
        ),
        column(width = 3,
               align = "center",
               h5("Numbers")
        )
    ),

    br(),

    fluidRow(
        column(width = 12,
               tags$div(id = "amr_test_placeholder")
        )
    ),

    fluidRow(

        br(),
        # "+" and "-" buttons
        column(width = 12,
               actionButton(inputId = "add_amr_test",
                            label = icon(name = "plus",
                                         lib = "font-awesome")),
               actionButton(inputId = "remove_amr_test",
                            label = icon(name = "times",
                                         lib = "font-awesome")),
               actionButton(inputId = "reset_button",
                            label = "RESET FIELDS")
        )
    ),

    br(),
    br()

)

###= SERVER
server <- function(input, output, session) {

    observe({

        toggleState(id = "remove_amr_test",
                    condition = input$add_amr_test > input$remove_amr_test + amr_test_values$reset)

        toggleState(id = "reset_button",
                condition = input$add_amr_test > input$remove_amr_test + amr_test_values$reset)

    })



    amr_test_values <- reactiveValues(val = 0,
                                      reset = 0)


    ### Defined the input number to count every row
    input_number <- reactive({

        input_number <- input$add_amr_test - input$remove_amr_test - amr_test_values$reset

        return(input_number)

    })




    observeEvent(input$add_amr_test, {

        amr_test_divId <- length(amr_test_values$val) + 1

        ###= Animal species
        if (!is.null(eval(parse(text = paste0("input$letters_", input_number() - 1))))) {

            letters_value = eval(parse(text = paste0("input$letters_", input_number() - 1)))

        } else {

            letters_value = ""

        }

        ###= Animal sample type
        if (!is.null(eval(parse(text = paste0("input$numbers_", input_number() - 1))))) {

            numbers_value = eval(parse(text = paste0("input$numbers_", input_number() - 1)))

        } else {

            numbers_value = ""

        }

        ###= Insert dynamic UI
        insertUI(
            selector = "#amr_test_placeholder",
            where = "beforeBegin",
            ui = tags$div(id = amr_test_divId,
                          tags$head(tags$style(HTML(".shiny-split-layout > div {overflow: visible;}"))),

                          br(),

                          fluidRow(
                              column(width = 3,
                                     splitLayout(cellWidths = c("18%", "82%"),
                                                 h5(paste0(input_number(), ". ")),
                                                 selectizeInput(inputId = paste0("letters_",
                                                                                 input_number()),
                                                                label =  NULL,
                                                                choices = c("A" = "",
                                                                            "A",
                                                                            "B",
                                                                            "C",
                                                                            "D",
                                                                            "E",
                                                                            "F",
                                                                            "F"),
                                                                selected = letters_value,
                                                                width = "100%",
                                                                options = list(create = TRUE))
                                     )
                              ),
                              column(width = 3,
                                     selectizeInput(inputId = paste0("numbers_",
                                                                     input_number()),
                                                    label = NULL,
                                                    choices = list("1" = "",
                                                                   "1" = "1",
                                                                   "2" = "2",
                                                                   "3" = "3",
                                                                   "4" = "4",
                                                                   "5" = "5"),
                                                    selected = numbers_value,
                                                    width = "100%")
                              )
                          )
            )
        )

        amr_test_values$val <- c(amr_test_values$val,
                                 amr_test_divId)

    })

    ###= Remove dynamic UI
    observeEvent(input$remove_amr_test, {

        removeUI(

            selector = paste0('#', amr_test_values$val[length(amr_test_values$val)])

        )

        amr_test_values$val <- amr_test_values$val[-length(amr_test_values$val)]

    })

    observeEvent(input$reset_button, {
        for(remove_value in 2:max(amr_test_values$val)) {
            removeUI(

                selector = paste0('#', remove_value)

            )
        }

        amr_test_values$reset <- input$add_amr_test - input$remove_amr_test
        amr_test_values$val <- 0
    })

}


###= Launch App
shinyApp(ui = ui, server = server)

我在这里添加了一个reset反应值:

observe({

    toggleState(id = "remove_amr_test",
                condition = input$add_amr_test > input$remove_amr_test + amr_test_values$reset)

    toggleState(id = "reset_button",
                condition = input$add_amr_test > input$remove_amr_test + amr_test_values$reset)

})



amr_test_values <- reactiveValues(val = 0,
                                  reset = 0)


### Defined the input number to count every row
input_number <- reactive({

    input_number <- input$add_amr_test - input$remove_amr_test - amr_test_values$reset

    return(input_number)

})

然后这个observeEvent

observeEvent(input$reset_button, {
    for(remove_value in 2:max(amr_test_values$val)) {
        removeUI(

            selector = paste0('#', remove_value)

        )
    }

    amr_test_values$reset <- input$add_amr_test - input$remove_amr_test
    amr_test_values$val <- 0
})

更新资料

根据您的编辑。

library(shiny)
library(shinyjs)

###= UI
ui <- fluidPage(

  br(),

  useShinyjs(),

  br(),

  fluidRow(
    column(width = 3,
           align = "center",
           h5("Letters")
    ),
    column(width = 3,
           align = "center",
           h5("Numbers")
    )
  ),

  br(),

  fluidRow(
    column(width = 12,
           tags$div(id = "amr_test_placeholder")
    )
  ),

  fluidRow(

    br(),
    # "+" and "-" buttons
    column(width = 12,
           actionButton(inputId = "add_amr_test",
                        label = icon(name = "plus",
                                     lib = "font-awesome")),
           actionButton(inputId = "remove_amr_test",
                        label = icon(name = "times",
                                     lib = "font-awesome")),
           actionButton(inputId = "reset_button",
                        label = "RESET FIELDS")
    )
  ),

  br(),
  br(),

  fluidRow(
    column(width = 6,
           tableOutput(outputId = "show_table")
    )
  )

)

###= SERVER
server <- function(input, output, session) {

  observe({

    toggleState(id = "remove_amr_test",
                condition = input$add_amr_test > input$remove_amr_test + amr_test_values$reset)

    toggleState(id = "reset_button",
                condition = input$add_amr_test > input$remove_amr_test + amr_test_values$reset)

  })



  amr_test_values <- reactiveValues(val = 0,
                                    reset = 0)


  ### Defined the input number to count every row
  input_number <- reactive({

    input_number <- input$add_amr_test - input$remove_amr_test - amr_test_values$reset + 1

    return(input_number)

  })




  observeEvent(input$add_amr_test, {

    amr_test_divId <- length(amr_test_values$val) + 1

    ###= Animal species
    if (!is.null(eval(parse(text = paste0("input$letters_", input_number() - 1))))) {

      letters_value = eval(parse(text = paste0("input$letters_", input_number() - 1)))

    } else {

      letters_value = "A"

    }

    ###= Animal sample type
    if (!is.null(eval(parse(text = paste0("input$numbers_", input_number() - 1))))) {

      numbers_value = eval(parse(text = paste0("input$numbers_", input_number() - 1)))

    } else {

      numbers_value = 1

    }

    ###= Insert dynamic UI
    insertUI(
      selector = "#amr_test_placeholder",
      where = "beforeBegin",
      ui = tags$div(id = amr_test_divId,
                    tags$head(tags$style(HTML(".shiny-split-layout > div {overflow: visible;}"))),

                    br(),

                    fluidRow(
                      column(width = 3,
                             splitLayout(cellWidths = c("18%", "82%"),
                                         h5(paste0(input_number(), ". ")),
                                         selectizeInput(inputId = paste0("letters_",
                                                                         input_number()),
                                                        label =  NULL,
                                                        choices = c("A" = "",
                                                                    "A",
                                                                    "B",
                                                                    "C",
                                                                    "D",
                                                                    "E",
                                                                    "F",
                                                                    "F"),
                                                        selected = letters_value,
                                                        width = "100%",
                                                        options = list(create = TRUE))
                             )
                      ),
                      column(width = 3,
                             selectizeInput(inputId = paste0("numbers_",
                                                             input_number()),
                                            label = NULL,
                                            choices = list("1" = "",
                                                           "1" = "1",
                                                           "2" = "2",
                                                           "3" = "3",
                                                           "4" = "4",
                                                           "5" = "5"),
                                            selected = numbers_value,
                                            width = "100%")
                      )
                    )
      )
    )

    amr_test_values$val <- c(amr_test_values$val,
                             amr_test_divId)

  }, ignoreNULL = FALSE)

  ###= Remove dynamic UI
  observeEvent(input$remove_amr_test, {

    removeUI(

      selector = paste0('#', amr_test_values$val[length(amr_test_values$val)])

    )

    amr_test_values$val <- amr_test_values$val[-length(amr_test_values$val)]

  })


  observeEvent(input$reset_button, {
    for(remove_value in 3:max(amr_test_values$val)) {
      removeUI(

        selector = paste0('#', remove_value)

      )
    }

    amr_test_values$reset <- input$add_amr_test - input$remove_amr_test
    amr_test_values$val <- c(0, 2)
  })



  ###= Dataset to check the dynamic updates of the responses
  response <- reactive({

    if (input_number() != 0 & !is.null(input[[paste0("letters_", input_number())]])) {

      response <- data.frame("Letters" = sapply(X = 1:input_number(),
                                                FUN = function(i) {

                                                  input[[paste0("letters_", i)]]

                                                }),
                             "Numbers" = sapply(X = 1:input_number(),
                                                FUN = function(i) {

                                                  input[[paste0("numbers_", i)]]

                                                })

      )

      return(response)

    } else {

      response <- NULL

    }

  })



  output$show_table <- renderTable({

    response()

  })

}



###= Launch App
shinyApp(ui = ui, server = server)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM