使用removeUI删除多个元素/使用标记包装多个元素$ div()为每个变量

时间:2016-11-07 03:57:27

标签: html css dynamic widget shiny

我被建议使用insertUI here,发现这是一个很棒的功能。以下代码允许使用insertUI为单个或多个元素生成控件窗口小部件,但是在合并removeUI相关部分时遇到了问题。尝试删除插入的UI元素的jQuery选项,但没有成功。我从Shiny dynamic UI找到了以下内容,即注意,如果要在一次调用中插入多个元素,则必须将它们包装在tagList()或标签$ div()中(后一个选项)有一个优点,你可以给它一个id,以便以后更容易引用或删除它。此外,comments here提供了一些线索,即tags$div(id="sepal.width.div", sliderInput("sepal.width.slider", ...)),但我缺乏HTML / CSS知识阻止了我前进。我正在考虑(a)用标签$ div()包装多个widget元素,为每个变量分配一个唯一的id,它将在removeUI中使用; (b)通过removeUI调用多个元素。

varnames <- names(iris[,1:4]) # names
varinit <- apply(iris[,1:4],2,median) # initival value used in slider
varmin <- apply(iris[,1:4],2,min) # min.
varmax <- apply(iris[,1:4],2,max) # max. 

ListofSelVars <<- vector(mode="character")

# control widgets for all elements
allControls <- lapply(setNames(varnames, varnames), function(x) {

   sliderInput(x, x, varmin[x], varmax[x], c(varmin[x], varinit[x]), 
               round = -2)   
})

ui <- navbarPage(
   tabPanel("Plot",
            sidebarLayout(
               sidebarPanel(
                  checkboxGroupInput("ConditioningVariables", "Conditioning variables (choose one or more):",
                                     varnames,inline = TRUE),
                  # add an action button
                  actionButton("add", "Update UI elements")
               ),
               mainPanel()
            )
   )
)

server <- function(input, output, session) {
   observeEvent(input$add, {
      insertUI(
         selector ='#add',
         where = "afterEnd",
         ui = allControls[setdiff(input$ConditioningVariables,ListofSelVars)]
      )

      ## removeUI related goes, here
      ## removeUI(selector=paste0())
      ## setdiff(ListofSelVars,input$ConditioningVariables) gives elements to be removed

      ## Global variable, keep track of elements that are selected

      ListofSelVars <<- input$ConditioningVariables

   })

}
shinyApp(ui, server)

1 个答案:

答案 0 :(得分:2)

这是工作代码。主要问题是这里的名称,即Sepal.Width。我使用id为div.Sepal.Width的div包装每个滑块,以便更容易删除。 removeUI需要一个jQuery选择器,因此看起来像#div.Sepal.Width这样的东西会起作用,但它不会,因为.本身就是一个jQuery选择器,意味着class,所以我们需要双倍逃避.。当然,您也可以在第一次创建div时删除.,从而避免麻烦......

varnames <- names(iris[,1:4]) # names
varinit <- apply(iris[,1:4],2,median) # initival value used in slider
varmin <- apply(iris[,1:4],2,min) # min.
varmax <- apply(iris[,1:4],2,max) # max. 

ListofSelVars <<- vector(mode="character")

# control widgets for all elements
allControls <- lapply(setNames(varnames, varnames), function(x) {
  tags$div(id=paste0("div.",x), sliderInput(x, x, varmin[x], varmax[x], c(varmin[x], varinit[x]), 
              round = -2))
})

ui <- fluidPage(

  titlePanel("Dynamic sliders"),

  sidebarLayout(
    sidebarPanel(
      checkboxGroupInput("ConditioningVariables", "Conditioning variables (choose one or more):",
                         varnames,inline = TRUE),
      # add an action button
      actionButton("add", "Update UI elements")
    ),

    mainPanel(
      uiOutput("plot_out")
    )
  )
)

server <- function(input, output, session) {
  observeEvent(input$add, {

    insertUI(
      selector ='#add',
      where = "afterEnd",
      ui = allControls[setdiff(input$ConditioningVariables,ListofSelVars)]
    )

    ListofRemoval <- setdiff(ListofSelVars,input$ConditioningVariables)

    for (item in ListofRemoval) {
      item = gsub(".", "\\.", item, fixed=TRUE)
      item = paste0("#div\\.", item)
      removeUI(item)
    }

    ListofSelVars <<- input$ConditioningVariables

  })

}
shinyApp(ui, server)