访问数据表行ID(由rowCallback生成)从shinyBS::addpopover()

huangapple go评论93阅读模式
英文:

access datatable row ID (generated with rowCallback) from shinyBS::addpopover()

问题

我试图使用shinyBS函数向数据表的各个单元格添加带有附加信息的弹出框,这是因为我希望它们是真正的弹出框,而不仅仅是数据表的标题属性。ShinyBS::addpopover()需要一个元素ID来附加弹出框。我已经成功将弹出框附加到整个数据表,现在我正尝试在行级别添加弹出框(然后再转向单元格级别),但我卡住了。

到目前为止,我的解决方案在很大程度上基于这个主题:https://stackoverflow.com/questions/61721873/insert-popify-for-radiobuttons-options

当前问题:使用rowCallback JS函数,数据表中的每一行现在都有自己的ID(tableRow_x),但ShinyBS::addpopover()似乎不认识这些ID。我怀疑可能可以向addpopover()的id参数中添加一些内容,以便它能够找到数据表中的ID,但我还没有找出具体方法。

重新表现(示例):

注意:在RStudio弹出浏览器中运行shiny时,必须首先在浏览器中的任何位置单击,然后弹出框才会开始显示。

  1. library(shinyBS)
  2. library(shiny)
  3. library(DT)
  4. library(shinyjs) ## needed to tamper with the HTML
  5. ui <- fluidPage(
  6. useShinyjs(),
  7. # need to include at least one bs element in ui
  8. bsTooltip(
  9. "foo",
  10. "This tooltip goes nowhere - it's there to make the tooltips defined with addPopover on the server side work"
  11. ) ,
  12. DTOutput("table")
  13. )
  14. server <- function(input, output, session) {
  15. # once the UI is loaded, call shinyBS::addPopover to attach popover to it
  16. session$onFlushed(function() {
  17. addPopover(session = session,
  18. id = "DataTables_Table_0",
  19. title = "information",
  20. content = "this is the popover on id DataTables_Table_0"
  21. )
  22. addPopover(session = session,
  23. id = "tableRow_3",
  24. title = "row information",
  25. content = "this is the popover on id tableRow_3")
  26. })
  27. output$table <-
  28. renderDataTable({
  29. datatable(data = iris,
  30. options = list(
  31. rowCallback = JS(
  32. "function( nRow, aData) {",
  33. "$(nRow).attr('id', 'tableRow_' + aData[0]);",
  34. "}"
  35. )
  36. ))
  37. })
  38. }
  39. # Run the application
  40. shinyApp(ui = ui, server = server)
英文:

I'm attempting to add popovers with additional information to individual cells of a datatable using shinyBS functions (because I'd like them to be proper popovers and not 'just' the datatable title attributes). ShinyBS::addpopover() requires an element ID for the element to attach a popover to. I've got this working for attaching a popover to an entire datatable, and now for the next step I'm attempting to add popovers at row level (before moving on to cell level) yet I am stuck.

My solution so far is very heavily based on this thread: https://stackoverflow.com/questions/61721873/insert-popify-for-radiobuttons-options

Current problem: Using a rowCallback JS function, each row in the datatable is now given it's own ID (tableRow_x) yet ShinyBS::addpopover() does not seem to recognize these IDs. I suspect it might be possible to add something to the id parameter of addpopover() to get it to find the id's within the datatable, but I haven't been able to figure out what.

reprex:

NB: when running the shiny in an rstudio pop up browser, it is necessary to first click anywhere in the browser before the popovers start showing.

  1. library(shinyBS)
  2. library(shiny)
  3. library(DT)
  4. library(shinyjs) ## needed to tamper with the HTML
  5. ui &lt;- fluidPage(
  6. useShinyjs(),
  7. # need to include at least one bs element in ui
  8. bsTooltip(
  9. &quot;foo&quot;,
  10. &quot;This tooltip goes nowhere - it&#39;s there to make the tooltips defined with addPopover on the server side work&quot;
  11. ) ,
  12. DTOutput(&quot;table&quot;)
  13. )
  14. server &lt;- function(input, output, session) {
  15. # once the UI is loaded, call shinyBS::addPopover to attach popover to it
  16. session$onFlushed(function() {
  17. addPopover(session = session,
  18. id = &quot;DataTables_Table_0&quot;,
  19. title = &quot;information&quot;,
  20. content = &quot;this is the popover on id DataTables_Table_0&quot;
  21. )
  22. addPopover(session = session,
  23. id = &quot;tableRow_3&quot;,
  24. title = &quot;row information&quot;,
  25. content = &quot;this is the popover on id tableRow_3&quot;)
  26. })
  27. output$table &lt;-
  28. renderDataTable({
  29. datatable(data = iris,
  30. options = list(
  31. rowCallback = JS(
  32. &quot;function( nRow, aData) {&quot;,
  33. &quot;$(nRow).attr(&#39;id&#39;, &#39;tableRow_&#39; +aData[0]);&quot;,
  34. &quot;}&quot;
  35. )
  36. ))
  37. })
  38. }
  39. # Run the application
  40. shinyApp(ui = ui, server = server)

`

答案1

得分: 0

它适用于 server=FALSErowCallback 选项而不是 rowCallback

  1. output$table &lt;-
  2. renderDT({
  3. datatable(
  4. data = iris,
  5. options = list(
  6. rowId = JS("function(data){return 'tableRow_' + data[0];}")
  7. )
  8. )
  9. }, server = FALSE)

没有尝试过 rowCallback

英文:

It works with server=FALSE and the rowId option instead of rowCallback:

  1. output$table &lt;-
  2. renderDT({
  3. datatable(
  4. data = iris,
  5. options = list(
  6. rowId = JS(&quot;function(data){return &#39;tableRow_&#39; + data[0];}&quot;)
  7. )
  8. )
  9. }, server = FALSE)

Didn't try with rowCallback.

答案2

得分: 0

以下是您要翻译的代码部分:

  1. Thought I'd give one more update (for future reference) before I move on out of reprex territory.
  2. The below version has &lt;strike&gt;a modified rowCallback function to assign ID&#39;s to the cell in the fourth column of each row&lt;/strike>. **Edit**: one more update - using the createdcell function to create the id tags, as suggested by St&#233;phane Laurent. In the createdcell JS function to the (zero-based) rowindex is increased with 1 to match it with the dataframe row indices for populating content using iris$Petal.Width[row] in a for loop.
  3. In the addpopover() call the option &#39;container = body&#39; is crucial in order to not make the popover mess up the datatable layout (as a result of plunking the popover div into the datatable).
  4. library(DT)
  5. library(shinyBS)
  6. library(shiny)
  7. library(shinyjs) ## needed to tamper with the HTML
  8. ui &lt;- fluidPage(
  9. useShinyjs(),
  10. ## need to include at least one bs element in ui
  11. bsTooltip(
  12. &quot;foo&quot;,
  13. &quot;This tooltip goes nowhere - it&#39;s there to make the tooltips defined with addPopover on the server side work&quot;
  14. ) ,
  15. DTOutput(&quot;table&quot;)
  16. )
  17. server &lt;- function(input, output, session) {
  18. ## once the UI is loaded, call shinyBS::addPopover to attach popover to it
  19. session$onFlushed(function() {
  20. addPopover(session,
  21. id = &quot;DataTables_Table_0&quot;,
  22. title = &quot;information&quot;,
  23. content = &quot;this is the popover on id DataTables_Table_0&quot;
  24. )
  25. for (row in c(1:nrow(iris))) {
  26. addPopover(session,
  27. id = paste0(&#39;cell_&#39;, row, &#39;_2&#39;),
  28. title = &quot;cell information&quot;,
  29. trigger = &#39;hover&#39;,
  30. content = paste(&#39;petal width =&#39;, iris$Petal.Width[row]),
  31. options = list( container=&#39;body&#39;)) # container= &#39;body&#39; makes it so that the popover div doesn&#39;t scoot over the next column/mess with the datatable lay-out.
  32. }
  33. })
  34. output$table &lt;-
  35. renderDataTable({
  36. datatable(data = iris[1:10,],
  37. options = list(
  38. columnDefs = list(
  39. list(visible=FALSE, targets=3),
  40. list(targets = &quot;_all&quot;,
  41. createdCell = DT::JS(&quot;
  42. function(td, cellData, rowData, row, col) {
  43. $(td).attr(&#39;id&#39;, &#39;cell_&#39;+(row+1)+&#39;_&#39;+col);
  44. }
  45. &quot;)
  46. ))))
  47. }, server = FALSE) #server = F is crucial for addpopover to find the new IDs
  48. }
英文:

Thought I'd give one more update (for future reference) before I move on out of reprex territory.

The below version has <strike>a modified rowCallback function to assign ID's to the cell in the fourth column of each row</strike>. Edit: one more update - using the createdcell function to create the id tags, as suggested by Stéphane Laurent. In the createdcell JS function to the (zero-based) rowindex is increased with 1 to match it with the dataframe row indices for populating content using iris$Petal.Width[row] in a for loop.

In the addpopover() call the option 'container = body' is crucial in order to not make the popover mess up the datatable layout (as a result of plunking the popover div into the datatable).

  1. library(DT)
  2. library(shinyBS)
  3. library(shiny)
  4. library(shinyjs) ## needed to tamper with the HTML
  5. ui &lt;- fluidPage(
  6. useShinyjs(),
  7. ## need to include at least one bs element in ui
  8. bsTooltip(
  9. &quot;foo&quot;,
  10. &quot;This tooltip goes nowhere - it&#39;s there to make the tooltips defined with addPopover on the server side work&quot;
  11. ) ,
  12. DTOutput(&quot;table&quot;)
  13. )
  14. server &lt;- function(input, output, session) {
  15. ## once the UI is loaded, call shinyBS::addPopover to attach popover to it
  16. session$onFlushed(function() {
  17. addPopover(session,
  18. id = &quot;DataTables_Table_0&quot;,
  19. title = &quot;information&quot;,
  20. content = &quot;this is the popover on id DataTables_Table_0&quot;
  21. )
  22. for (row in c(1:nrow(iris))) {
  23. addPopover(session,
  24. id = paste0(&#39;cell_&#39;, row, &#39;_2&#39;),
  25. title = &quot;cell information&quot;,
  26. trigger = &#39;hover&#39;,
  27. content = paste(&#39;petal width =&#39;, iris$Petal.Width[row]),
  28. options = list( container=&#39;body&#39;)) # container= &#39;body&#39; makes it so that the popover div doesn&#39;t scoot over the next column/mess with the datatable lay-out.
  29. }
  30. })
  31. output$table &lt;-
  32. renderDataTable({
  33. datatable(data = iris[1:10,],
  34. options = list(
  35. columnDefs = list(
  36. list(visible=FALSE, targets=3),
  37. list(targets = &quot;_all&quot;,
  38. createdCell = DT::JS(&quot;
  39. function(td, cellData, rowData, row, col) {
  40. $(td).attr(&#39;id&#39;, &#39;cell_&#39;+(row+1)+&#39;_&#39;+col);
  41. }
  42. &quot;)
  43. ))))
  44. }, server = FALSE) #server = F is crucial for addpopover to find the new IDs
  45. }
  46. # Run the application
  47. shinyApp(ui = ui, server = server)

huangapple
  • 本文由 发表于 2023年3月15日 19:13:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75743935.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定