【问题标题】:Nest "Add an Input" Within "Add an Input" in R Shiny在 R Shiny 的“添加输入”中嵌套“添加输入”
【发布时间】:2018-11-20 23:23:29
【问题描述】:

在 R Shiny 中,我可以使用以下技术添加带有 actionButton 的附加输入字段:R Shiny: How to create an "Add Field" Button(称为 Section A)。现在我想允许用户在 A 部分中添加额外的输入字段。基本上,我想在“添加输入”中嵌套“添加输入”。

我使用引用线程中的示例制作了一个模型应用程序。对于这个特定示例,目标是允许用户通过点击他们使用“添加文本”按钮创建的每个文本框下的“添加评论”按钮来添加多个 cmets。

但是,如果嵌套了 observeEvent({}),我收到了一个错误:as.vector 中的错误:无法将类型“环境”强制转换为“字符”类型的向量。

ui <- shinyUI(fluidPage(
  titlePanel(""),
  sidebarLayout(
    sidebarPanel(
      actionButton("addText","Add Text"),
      uiOutput("txtOutput"),
      actionButton("getTexts","Get Input Values")
    ),

    # Show a plot of the generated distribution
    mainPanel(
      verbatimTextOutput("txtOut"),
      verbatimTextOutput("cmtOut")
    )
  )))

server <- shinyServer(function(input,output,session){

  ids <<- NULL

  observeEvent(input$addText,{
    if (is.null(ids)){
      ids <<- 1
    }else{
      ids <<- c(ids, max(ids)+1)
    }

    idsa <<- NULL

    output$txtOutput <- renderUI({
        lapply(1:length(ids),function(i){
          textInput(paste0("txtInput",ids[i]), sprintf("Text Input #%d",ids[i]))

          uiOutput(outputId = paste0("cmtOutput", ids[i]))
          actionButton(inputId = paste0("addComment", ids[i]), "Add Comment")


          observeEvent(input[[paste0("addComment",ids[i])]],{
            if (is.null(idsa)){
              idsa <<- 1
            }else{
              idsa <<- c(idsa, max(idsa)+1)
            }
            output[[paste0("cmtOutput",ids[i])]] <- renderUI({
                lapply(1:length(idsa), function(i){
                  textInput(paste0("cmtInput", ids[i], "_", idsa[i]), sprintf("Comment Input #%d", idsa[i]))
                })
            })
          })
          })
    })
  })

  observeEvent(input$getTexts,{
    if(is.null(ids)){
      output$txtOut <- renderPrint({"No textboxes"})
      output$cmtOut <- renderPrint({"No comments"})
    }else{
      txtOut <- list()

      # Get ids for textboxes
      txtbox_ids <- sapply(1:length(ids),function(i){
        paste0("txtInput",ids[i],sep="")
      })

      # Get values
      for(i in 1:length(txtbox_ids)){
        txtOut[[i]] <- sprintf("Txtbox #%d has value: %s",i,input[[ txtbox_ids[i] ]])
      }
        output$txtOut <- renderPrint({txtOut})
        if(is.null(idsa)){
          output$cmtOut <- renderPrint({"No comments"})
        }else{
          cmtOut <- list()

          # Get ids for textboxes
          cmtbox_ids <- sapply(1:length(idsa),function(i){
            paste0("cmtInput",ids[i], "_", idsa[i],sep="")
          })

          # Get values
          for(i in 1:length(cmtbox_ids)){
            cmtOut[[i]] <- sprintf("Comment box #%d has value: %s",i,input[[ cmtbox_ids[i] ]])
          }

      output$cmtOut <- renderPrint({cmtOut})
        }
    }
  })

})

shinyApp(ui=ui,server=server)

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    我自己想通了。只是为遇到类似问题的人发帖。下面是模型的代码。 注意使用 if (idsc[i] != input[[paste0("addComment", idsR$v[i])]]) 由于缺少此语法,当您单击“添加文本”两次,并为第一个文本框单击“添加注释”一次时,您将看到添加了两个 cmets。 还要注意使用 if (length(idsaR$v[[i]]) != 0){ idsaR$v[[i]] <<- c(idsaR$v[[i]], max(idsaR$v[[i]])+1) } else{ idsaR$v[[i]] <<- c(1) },如果省略了,在你为文本框#2 添加 cmets 并想返回为文本框 #1 添加 cmets 后,会出现错误。

    ui <- shinyUI(
    
    
    
    
      fluidPage(
      titlePanel(""),
      sidebarLayout(
        sidebarPanel(
          actionButton("addText","Add Text"),
          uiOutput("txtOutput"),
          actionButton("getTexts","Get Input Values")
        ),
    
        # Show a plot of the generated distribution
        mainPanel(
          verbatimTextOutput("txtOut"),
          verbatimTextOutput("cmtOut")
        )
      )))
    
    server <- shinyServer(function(input,output,session){
    
      ids <<- NULL
      idsR <<- reactiveValues(v = c())
      idsaR <<- reactiveValues(v = list())
      idsc <<- c()
    
    
      observeEvent(input$addText,{
        if (is.null(ids)){
          ids <<- 1
        }else{
          ids <<- c(ids, max(ids)+1)
        }
        idsR$v <<- ids
    
        output$txtOutput <- renderUI({
            lapply(1:length(ids),function(i){
             tagList(
             textInput(paste0("txtInput",idsR$v[i]), sprintf("Text Input #%d",idsR$v[i])),
    
             uiOutput(outputId = paste0("cmtOutput", idsR$v[i])),
             actionButton(inputId = paste0("addComment", idsR$v[i]), "Add Comment")
              )
    
    
    
              })
        })
      })
    
      idsc <<- c()
    
    observe({
    if (length(idsR$v)!= 0){
    lapply(1:length(idsR$v), function(i){
      idsc[i] <<- 0
      observeEvent(input[[paste0("addComment", idsR$v[i])]],{
    
        if (idsc[i] != input[[paste0("addComment", idsR$v[i])]]){
          if (length(idsaR$v) < i ){
            idsaR$v[[i]] <<- c(1)
          }else{
            if (length(idsaR$v[[i]]) != 0){
            idsaR$v[[i]] <<- c(idsaR$v[[i]], max(idsaR$v[[i]])+1)
            }
            else{
            idsaR$v[[i]] <<- c(1)
          }
          }
        }
    
        idsc[i] <<- input[[paste0("addComment", idsR$v[i])]]
    
    
        output[[paste0("cmtOutput",idsR$v[i])]] <- renderUI({
          lapply(1:length(idsaR$v[[i]]), function(j){
            textInput(paste0("cmtInput", idsR$v[i], "_", idsaR$v[[i]][j]), sprintf("Comment Input #%d, #%s", idsR$v[i], idsaR$v[[i]][j]))
          })
        })
      })
    })
    }
    })
    
    
    
    
      observeEvent(input$getTexts,{
        if(is.null(idsR$v)){
          output$txtOut <- renderPrint({"No textboxes"})
          output$cmtOut <- renderPrint({"No comments"})
        }else{
          txtOut <- list()
          cmtOut <- list()
          cmtbox_ids <- list()
    
          # Get ids for textboxes
          txtbox_ids <- sapply(1:length(idsR$v),function(i){
            paste0("txtInput",idsR$v[i],sep="")
          })
    
          # Get values
          for(i in 1:length(txtbox_ids)){
            txtOut[[i]] <- sprintf("Txtbox #%d has value: %s",i,input[[ txtbox_ids[i] ]])
    
            if(is.null(idsaR$v)){
              cmtOut <- list("No comments")
            }else{
              cmtOut[[i]] <- list()
              if (length(idsaR$v) >= i){
              # Get ids for commentboxes for the ith textbox
              cmtbox_ids[[i]] <- sapply(1:length(idsaR$v[[i]]),function(j){
                paste0("cmtInput",idsR$v[i], "_", idsaR$v[[i]][j])
              })
    
              # Get values
              for (j in 1:length(cmtbox_ids[[i]])){
                if(is.null(idsaR$v[[i]])){
                cmtOut[[i]] <- c("No comments")
                  }else{
                cmtOut[[i]][j] <- sprintf("Comment box #%d has value: %s",j,input[[ cmtbox_ids[[i]][j] ]])
                  }
              }
            }else{
              cmtOut[[i]] <- c("No comments")
            }
    
    
            }
          }
            output$txtOut <- renderPrint({txtOut})
            output$cmtOut <- renderPrint({cmtOut})
    
        }
      })
    
    })
    
    shinyApp(ui=ui,server=server)
    

    【讨论】:

      猜你喜欢
      • 2018-06-04
      • 2019-10-17
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 2020-07-06
      • 2021-12-09
      • 1970-01-01
      • 2019-02-21
      相关资源
      最近更新 更多