使用actionButtons

时间:2016-05-29 00:15:26

标签: r shiny

我正在尝试使用索引添加和删除uiOutput元素以跟踪每个元素。列表中有actionButton个添加元素,删除所选项目的每个元素都有一个 x 按钮,如下图所示:

Shiny dynamic elements example

我正在使用包含uiserver代码的单个.Rmd文件。我目前的解决方案(我无法生成上面显示的所需功能---它基本上什么都不做)如下:

actionButton("addFilter", "Add filter", icon=icon("plus", class=NULL, lib="font-awesome"))

i <- 0

observeEvent(input$addFilter, {
  i <<- i + 1
  uiOutput(paste("filterPage",i,sep=""))

  output[[paste("filterPage",i,sep="")]] = renderUI({
    fluidPage(
      fluidRow(
        column(6, selectInput(paste("filteringFactor",i,sep=""), "Choose factor to filter by:",
                              choices=c("factor A", "factor B", "factor C"), selected="factor B",
                              width="100%")),
        column(6, actionButton(paste("removeFactor",i,sep=""), "",
                               icon=icon("times", class = NULL, lib = "font-awesome")))
      )
    )
  })

  observeEvent(input[[paste("removeFactor",i,sep="")]], {
    output[[paste("filterPage",i,sep="")]] = renderUI({})
  })

})

当我将uiOutput和删除按钮observeEvent放在添加按钮observeEvent之外时代码可以正常工作,但我需要为每个索引创建一个单独的语句,如下所示:

uiOutput(paste("filterPage",1,sep=""))
uiOutput(paste("filterPage",2,sep=""))
uiOutput(paste("filterPage",3,sep=""))
uiOutput(paste("filterPage",4,sep=""))

actionButton("addFilter", "Add filter", icon=icon("plus", class=NULL, lib="font-awesome"))

i <- 0

observeEvent(input$addFilter, {
  i <<- i + 1
  output[[paste("filterPage",i,sep="")]] = renderUI({
    fluidPage(
      fluidRow(
        column(6, selectInput(paste("filteringFactor",i,sep=""), "Choose factor to filter by:",
                              choices=c("factor A", "factor B", "factor C"), selected="factor B",
                              width="100%")),
        column(6, actionButton(paste("removeFactor",i,sep=""), "",
                               icon=icon("times", class = NULL, lib = "font-awesome")))
      )
    )
  })
})

observeEvent(input[[paste("removeFactor",1,sep="")]], {
  output[[paste("filterPage",1,sep="")]] = renderUI({})
})
observeEvent(input[[paste("removeFactor",2,sep="")]], {
  output[[paste("filterPage",2,sep="")]] = renderUI({})
})
observeEvent(input[[paste("removeFactor",3,sep="")]], {
  output[[paste("filterPage",3,sep="")]] = renderUI({})
})
observeEvent(input[[paste("removeFactor",4,sep="")]], {
  output[[paste("filterPage",4,sep="")]] = renderUI({})
})

我无法进行for循环或lapply调用工作(它看起来像我不明白的范围问题)。由于事先不知道元素的数量,硬编码值对我来说不起作用。有人知道如何使这项工作?谢谢。

2 个答案:

答案 0 :(得分:4)

我有一个适合你的方法,在后端可能不漂亮,但让生活变得轻松。我建议你将所有元素嵌套在一起。使uiOutput号码i包含下一个uiOutput。这样,您可以连续添加它们,而无需担心元素的大小或总数。性能方面,这也没关系,特别是因为我不认为你创造了数以千计的过滤器。有关更多详细信息,请参阅代码。

对于删除,您已经看到跟踪所有按钮输入值很繁琐。因此,我建议您设计一个要观察的变量,它会告诉您已单击的元素编号。我们可以使用自定义onclick函数为我们的按钮实现此功能,将按钮编号发送到一个输入变量。您可能希望熟悉JavaScript客户端函数Shiny.onInputChange。简单地说:它在给定变量名下的R后端发送一个值。

删除相应的ui元素很简单。

如果您想了解更多内容并设计更清晰,更精细的解决方案,请尝试this page及相关问题。在那里,您可以获得有关如何在没有常用的单uiOutput包装器的情况下设计和添加动态ui块的输入。

下面的代码(我制作了一个常规的ui-server应用程序):

library(shiny)

ui <- shinyUI(
  fluidPage(

    actionButton("addFilter", "Add filter", icon=icon("plus", class=NULL, lib="font-awesome")),

    uiOutput("filterPage1")
  )
)

server <- function(input, output){
  i <- 0

  observeEvent(input$addFilter, {
    i <<- i + 1
    output[[paste("filterPage",i,sep="")]] = renderUI({
      list(
        fluidPage(
          fluidRow(
            column(6, selectInput(paste("filteringFactor",i,sep=""), "Choose factor to filter by:",
                                choices=c("factor A", "factor B", "factor C"), selected="factor B",
                                width="100%")),
            column(6, actionButton(paste("removeFactor",i,sep=""), "",
                                 icon=icon("times", class = NULL, lib = "font-awesome"),
                                 onclick = paste0("Shiny.onInputChange('remove', ", i, ")")))
          )
        ),
        uiOutput(paste("filterPage",i + 1,sep=""))
      )
    })
  })

  observeEvent(input$remove, {
    i <- input$remove

    output[[paste("filterPage",i,sep="")]] <- renderUI({uiOutput(paste("filterPage",i + 1,sep=""))})
  })
}

shinyApp(ui, server)

答案 1 :(得分:0)

此链接可以帮助您吗?

http://shiny.rstudio.com/gallery/creating-a-ui-from-a-loop.html

可能无法保持uiOutput元素的数量动态,但您希望在实践中出现多少元素?您是否可以创建10个或20个并在按下按钮时打开和关闭它们?