我试图在同一个insertUI块中插入一个对selectInput有反应的UI。从概念上讲,insertUI充当一种向用户呈现selectInput的形式,然后基于他/她的选择,呈现一个伴随的selectizeInput。这个想法是,这两个小部件属于相同的输出div,如果用户愿意,可以使用相同的removeUI按钮将其删除。
我从here出发,并且尝试使this answer适应一个相对类似的问题,但是当我单击“添加新表单”时,所有尝试都破坏了该应用程序,返回以下警告:
Warning: Error in if: argument is of length zero
88: tag
87: tags$div
86: div
85: column
76: observeEventHandler [~/.active-rstudio-document#33]
5: runApp
3: print.shiny.appobj
1: source
我怀疑我的问题是我试图提取未完全创建的对象的输入值。我希望这不会成为问题,期望selectizeInput是根据selectInput的默认值呈现的,并且如果并且当用户更改selectInput选择时,会重新呈现selectizeInput。不再确定是否可以使用insertUI(还有renderUI的任务)来实现。关于反应性,我还有很多要学习的东西,并且可能有一种更简单的方法来解决这个问题。
这是我上次尝试的简化版本:
library(shiny)
library(shinyjs)
library(shinyWidgets)
ui <- navbarPage(
tabPanel(
useShinyjs(),
hr(),
h3("Click the button to add a new form:"),
fluidRow(
actionBttn(
inputId = "new_form",
label = "Add new form",
color = "primary",
style = "simple",
size = "sm"
)
),
fluidRow(div(id = 'placeholder_new_form'))
)
)
server <- function(input, output, session) {
observeEvent(input$new_form, {
# make ids for the plot, the remove button, and the element to remove
id_add <- paste0("id_", input$new_form)
remove_id <- paste0("remove_", input$new_form)
ele_id <- paste0("ele_", input$new_form)
choice_id <- paste0("choice_", input$new_form)
insertUI(
selector = "#placeholder_new_form",
where = "afterEnd",
ui = tags$div(
id = ele_id,
fluidRow(
column (
width = 6,
align = "center",
selectInput(
inputId = choice_id,
label = "Select a choice",
choices = c("Choice 1", "Choice 2", "Choice 3"),
width = "100%")
),
column(
width = 6,
align = "center",
if(input$choice_id == "Choice 1"){
selectizeInput(inputId = "choice_1_options",
label = "Select option from Choice 1:",
choices = c("", "Option 1", "Option 2", "Option 3"),
options = list(maxItems = 1, placeholder = "Start typing option here...", create = TRUE),
width = "100%")
} else if (input$choice_id == "Choice 2"){
selectizeInput(inputId = "choice_2_options",
label = "Select option from Choice 2:",
choices = c("", "Option 1", "Option 2", "Option 3"),
options = list(maxItems = 1, placeholder = "Start typing option here...", create = TRUE),
width = "100%")
} else {
selectizeInput(inputId = "choice_3_options",
label = "Select option from Choice 3:",
choices = c("", "Option 1", "Option 2", "Option 3"),
options = list(maxItems = 1, placeholder = "Start typing option here...", create = TRUE),
width = "100%")
}
)
),
actionButton(remove_id, "Remove form")
),
observeEvent(input[[remove_id]], {
removeUI(
selector = paste0("#", ele_id)
)
})
)
})
}
shinyApp(ui = ui, server = server)
我想为用户提供的关键功能是每个新表单都包含selectInput和selectizeInput,他/他可以通过单个removeUI按钮轻松删除整个表单,并添加与s一样多的表单。 /他想要。
在此先感谢您的更正,建议和见解。