我想在页面上有一个可变数量的相同actionButton(),它们都由一个observeEvent()函数处理。
例如,在一个可变长度的表格表格中,我希望每个内部表格都有一个链接到该表格的更多信息的按钮。
在标准HTML中,您可以使用一个简单的表单来执行此操作,您可以使用隐藏的输入来指定内部表号,如下所示:
<form ...>
<input id="table_number" type="hidden" value="1"/>
<input type="submit" value="Examine"/>
</form>
按下按钮时,您可以检查隐藏的输入以查看它是哪一个。
有没有办法在Shiny中做到这一点?我想出的唯一解决方案是给每个actionButton()它自己的inputId。这需要为每个按钮单独的observeEvent()。这些必须提前创建,强加最多数量的按钮。
答案 0 :(得分:3)
这只花了我几年时间,但我现在对这个问题有了更好的答案。您可以使用JavaScript / jQuery函数在文档中的每个按钮上放置一个on-click事件处理程序,然后使用 Shiny.onInputChange()函数传递按钮的ID({{1已经点击了Shiny代码中的单个观察者。
在One observer for all buttons in Shiny using JavaScript/jQuery
上有代码示例的完整说明答案 1 :(得分:2)
您可以使用闪亮的模块:您可以使用相同的可变数量的actionButton
。这些在ab_moduleUI
部分中定义。它们由自己的observeEvent
处理,但只需在ab_module
部分定义一次。
lapply
可以创建任意数量的actionButton
。
编辑:您不必事先指定按钮数:使用renderUI
在服务器端生成UI元素。
出于演示目的,我添加了numericInput
来增加/减少要渲染的模块数量。
# UI part of the module
ab_moduleUI <- function(id){
ns <- NS(id)
tagList(
fluidRow(
actionButton(ns("btn"), paste("ActionButton", id, sep="-")),
textOutput(ns("txt"))
)
)
}
# Server part of the module
ab_module <- function(input, output, session){
observeEvent(input$btn,{
output$txt <- renderText("More information shown")
})
}
# UI
ui <- fluidPage(
# lapply(paste0("mod", 1:no_btn), ab_moduleUI)
numericInput("num", "Number of buttons to show" ,value = 5, min = 3, max = 10),
uiOutput("ui")
)
# Server side
server <- function(input, output, session){
observeEvent(input$num, {
output$ui <- renderUI({
lapply(paste0("mod", 1:input$num), ab_moduleUI)
})
lapply(paste0("mod", 1:input$num), function(x) callModule(ab_module, x))
})
}
shinyApp(ui, server)
详细了解闪亮模块here
答案 2 :(得分:0)
关于使用Shiny模块回答我原来的问题......
我想要的是在页面上有多个按钮可以由单个observeEvent()
处理的方法,这很容易用传统的HTML表单,如原始问题所示。
actionInput <- function(id) {
ns <- NS(id)
tagList(
textInput(ns("text"), label=NULL, value=id),
actionButton(ns("button"), "OK")
)
}
action <- function(input, output, session) {
eventReactive(input$button, {
return(input$text)
})
}
ui <- fluidPage(fluidRow(column(4, actionInput("b1")),
column(4, actionInput("b2")),
column(4, uiOutput("result"))))
server <-function(input, output, session) {
b1 <- callModule(action, "b1")
observeEvent(b1(), {
output$result = renderText(b1())
})
b2 <- callModule(action, "b2")
observeEvent(b2(), {
output$result = renderText(b2())
})
}
shinyApp(ui = ui, server = server)
(在实际应用中,我会使textInputs
不可见,因为它们只是提供按下按钮的ID。)
对于每个按钮,此解决方案仍需要主服务器中的observeEvent()
。有可能以其他方式使用模块来解决问题,但我无法弄明白。
我的原始替代方案,在每个按钮的主服务器中使用单独的observeEvent()
,实际上比这个演示代码的扩展对于一百个或更多按钮更简单。