【问题标题】:How to add/remove input fields dynamically by a button in shiny如何通过闪亮的按钮动态添加/删除输入字段
【发布时间】:2015-10-05 21:32:31
【问题描述】:

我一直在尝试找到一个解决方案,如何使用闪亮的按钮添加和删除输入字段。我没有源代码,因为我没有取得太大进展,但是这个 jQuery 示例 (http://www.mkyong.com/jquery/how-to-add-remove-textbox-dynamically-with-jquery/) 很好地说明了我想要完成的工作。这可能是闪亮的还是我应该使用闪亮的js来做到这一点?提前谢谢!

【问题讨论】:

    标签: dynamic input shiny shinyjs


    【解决方案1】:

    编辑:我阅读了更多 jQuery 示例,并添加了一个代码 sn-p 执行我认为您正在寻找的操作。

    我不知道 jQuery,所以我无法从示例链接中获得太多信息。我猜测你想要什么,但我认为关键的想法是使用 renderUIuiOutput,即使我在这里的建议没有抓住重点。

    切换 ui 元素:

    如果你特别不想使用shinyjs,你可以这样做:

    library(shiny)
    
    ui <- shinyUI(fluidPage(
    
      actionButton("btn", "Toggle Textbox"),
    
      textOutput("btn_val"),
      uiOutput("textbox_ui")
    
    ))
    
    server <- shinyServer(function(input, output, session) {
    
      output$btn_val <- renderPrint(print(input$btn))
    
      textboxToggle <- reactive({
    
        if (input$btn %% 2 == 1) {
          textInput("textin", "Write something:", value = "Hello World!")
        }
    
      })
    
      output$textbox_ui <- renderUI({ textboxToggle() })
    
    })
    
    shinyApp(ui, server)
    

    添加和删除元素:

    在阅读了一些 jQuery 示例之后,我认为这与您正在寻找的内容相似:

    library(shiny)
    
    ui <- shinyUI(fluidPage(
    
      sidebarPanel(
    
          actionButton("add_btn", "Add Textbox"),
          actionButton("rm_btn", "Remove Textbox"),
          textOutput("counter")
    
        ),
    
      mainPanel(uiOutput("textbox_ui"))
    
    ))
    
    server <- shinyServer(function(input, output, session) {
    
      # Track the number of input boxes to render
      counter <- reactiveValues(n = 0)
    
      observeEvent(input$add_btn, {counter$n <- counter$n + 1})
      observeEvent(input$rm_btn, {
        if (counter$n > 0) counter$n <- counter$n - 1
      })
    
      output$counter <- renderPrint(print(counter$n))
    
      textboxes <- reactive({
    
        n <- counter$n
    
        if (n > 0) {
          lapply(seq_len(n), function(i) {
            textInput(inputId = paste0("textin", i),
                      label = paste0("Textbox", i), value = "Hello World!")
          })
        }
    
      })
    
      output$textbox_ui <- renderUI({ textboxes() })
    
    })
    
    shinyApp(ui, server)
    

    这种方法的问题是每次按下添加或删除按钮时,所有输入框都会重新呈现。这意味着您可能对它们进行的任何输入都会消失。

    我认为您可以通过将输入框的当前输入值保存到 reactiveValues 对象中,并使用 @ 将对象中的值设置为重新渲染输入框的起始值来解决这个问题textInput 中的 987654328@ 选项。不过,我将暂时保留它的实现。

    【讨论】:

    【解决方案2】:

    感谢@Mikko Marttila 的回答。我能够将它用于我的目的。另外,关于所有输入框在此处重新渲染的问题,我发现了一个解决方案,可以从 answer 中解决。您可以使用reactiveValuesToList() 保存所有用户输入,然后相应地调用响应式列表以将每个值设置为lapply() 语句中相应用户的输入。

    library(shiny)
    
    ui <- shinyUI(fluidPage(
    
      sidebarPanel(
    
        actionButton("add_btn", "Add Textbox"),
        actionButton("rm_btn", "Remove Textbox"),
        textOutput("counter")
    
      ),
    
      mainPanel(uiOutput("textbox_ui"))
    
    ))
    
    server <- shinyServer(function(input, output, session) {
    
      # Track the number of input boxes to render
      counter <- reactiveValues(n = 0)
    
      # Track all user inputs
      AllInputs <- reactive({
        x <- reactiveValuesToList(input)
      })
    
      observeEvent(input$add_btn, {counter$n <- counter$n + 1})
      observeEvent(input$rm_btn, {
        if (counter$n > 0) counter$n <- counter$n - 1
      })
    
      output$counter <- renderPrint(print(counter$n))
    
      textboxes <- reactive({
    
        n <- counter$n
    
        if (n > 0) {
          isolate({
            lapply(seq_len(n), function(i) {
              textInput(inputId = paste0("textin", i),
                        label = paste0("Textbox", i), 
                        value = AllInputs()[[paste0("textin", i)]])
            })
          })
        }
    
      })
    
      output$textbox_ui <- renderUI({ textboxes() })
    
    })
    
    shinyApp(ui, server)
    

    编辑:我将lapply() 语句包装在isolate() 中,因为当您尝试在该字段中输入时重新渲染框时它会很烦人

    【讨论】:

      猜你喜欢
      • 2017-05-05
      • 1970-01-01
      • 2023-04-02
      • 2019-04-30
      • 2019-05-01
      • 2019-04-30
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多