如何从可反应中的单元格呈现按钮触发带有observeEvent的modalBox?
Posted
技术标签:
【中文标题】如何从可反应中的单元格呈现按钮触发带有observeEvent的modalBox?【英文标题】:How to trigger a modalBox with observeEvent from a cell rendered button in a reactable? 【发布时间】:2021-12-04 03:48:12 【问题描述】:继this 的帖子之后,我想知道为什么当我单击单元格呈现按钮时,observeEvent()
内部的showModal()
不会被触发?
我给按钮observeEvent()
应该听的固定ID“字符”,然后打开模式框。但它没有。
如果我在 ShinyApp UI 中放置一个按钮,observeEvent()
会对 inputid 做出反应,或者如果我将它放置在一个可反应的地方,有什么区别?
library(shiny)
library(reactable)
library(tidyverse)
data = dplyr::starwars %>%
select(name, height, mass, sex, species, homeworld)
ui = fluidPage(
column(width = 6, style = "margin-top: 50px;",
reactableOutput("table"))
)
server = function(input, output, session)
output$table = renderReactable(
reactable(data = data,
height = 600,
defaultPageSize = 20,
columns = list(
name = colDef(
cell = function(value)
div(htmltools::tags$button(value, class = "action-button", id = "character"))
))))
observeEvent(input$character,
showModal(modalDialog(title = "Test"))
)
shinyApp(ui, server)
【问题讨论】:
【参考方案1】:reactable 包提供了许多如何使用它的示例,包括每行中的 custom action。该示例有一个“详细信息”列,它显示了看起来像按钮的元素。使用 javascript 函数,它可以识别对详细信息列的点击并采取相应措施。
将此作为附加参数添加到renderReactable
中的reactable
调用。
reactable(
data = data,
height = 600,
defaultPageSize = 20,
...
onClick = JS("function(rowInfo, colInfo)
// Only handle click events on the 'details' column
if (colInfo.id !== 'details')
return
// Send the click event to Shiny
if (window.Shiny)
Shiny.setInputValue('foo', 'bar')
")
)
Shiny.setInputValue("foo", "bar")
将导致服务器的 input$foo 设置为“bar”。这会导致一个 Shiny 事件,您可以在服务器中捕获该事件,例如,使用观察者。见this tutorial about Javascript in R for details。
请注意:reactable 的作者不建议使用此功能,因为“键盘用户目前无法访问自定义点击操作”(引自手册 2021-10-16)。如果可访问性或其他使用键盘的原因与您无关,您可以使用此解决方案。
关于“类”解决方案的注意事项:我不建议使用class = "action-button"
,因为我认为它是一个脆弱的构造。这不是创建输入绑定的正确方法,我很惊讶它完全可以工作。
我知道的唯一官方支持表格行按钮的包是DataTables 和Buttons extension。
【讨论】:
我从 reactabel 包中知道这些示例,但这些示例都没有进入我在帖子中指出的方向。我需要触发一个模态框,我可以在其中编写 R 代码,而不是 JS 代码。 “显示看起来像按钮的元素”是什么意思?这些是按钮,不是吗? 我不明白。使用Shiny.setInputValue
,您可以创建可以通过观察者在 R 服务器函数中处理的事件,并编写您需要编写的任何 R 代码。缺少什么?
关于ui元素看起来像按钮的问题:实际上,它们是假的。单击不响应单击按钮,而是单击整个表格单元格。你可以试试看。即使您单击按钮旁边的几个像素,该演示也会响应您的点击。
您有权使用onClick
参数中的Shiny.setInputValue
处理R 服务器函数中的各种事件,这对我非常有用,谢谢!不过我想知道为什么cell = function(value)div(tags$button(value, onclick = "Shiny.setInputValue('foo', 'bar', priority: 'event')"))
不起作用,因为它基本上看起来完全一样。
不同之处在于两个函数的规范。 reactable 知道 onClick
参数。它是规范的一部分,它提供了运行你放在那里的任何 Javascript 的必要逻辑。另一方面,tags$button
按钮不知道onClick
。它接受每个命名参数并将其强制转换为 HTML 属性。但是,当然,这对你没有好处。以上是关于如何从可反应中的单元格呈现按钮触发带有observeEvent的modalBox?的主要内容,如果未能解决你的问题,请参考以下文章