英文:
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时,必须首先在浏览器中的任何位置单击,然后弹出框才会开始显示。
library(shinyBS)
library(shiny)
library(DT)
library(shinyjs) ## needed to tamper with the HTML
ui <- fluidPage(
useShinyjs(),
# need to include at least one bs element in ui
bsTooltip(
"foo",
"This tooltip goes nowhere - it's there to make the tooltips defined with addPopover on the server side work"
) ,
DTOutput("table")
)
server <- function(input, output, session) {
# once the UI is loaded, call shinyBS::addPopover to attach popover to it
session$onFlushed(function() {
addPopover(session = session,
id = "DataTables_Table_0",
title = "information",
content = "this is the popover on id DataTables_Table_0"
)
addPopover(session = session,
id = "tableRow_3",
title = "row information",
content = "this is the popover on id tableRow_3")
})
output$table <-
renderDataTable({
datatable(data = iris,
options = list(
rowCallback = JS(
"function( nRow, aData) {",
"$(nRow).attr('id', 'tableRow_' + aData[0]);",
"}"
)
))
})
}
# Run the application
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.
library(shinyBS)
library(shiny)
library(DT)
library(shinyjs) ## needed to tamper with the HTML
ui <- fluidPage(
useShinyjs(),
# need to include at least one bs element in ui
bsTooltip(
"foo",
"This tooltip goes nowhere - it's there to make the tooltips defined with addPopover on the server side work"
) ,
DTOutput("table")
)
server <- function(input, output, session) {
# once the UI is loaded, call shinyBS::addPopover to attach popover to it
session$onFlushed(function() {
addPopover(session = session,
id = "DataTables_Table_0",
title = "information",
content = "this is the popover on id DataTables_Table_0"
)
addPopover(session = session,
id = "tableRow_3",
title = "row information",
content = "this is the popover on id tableRow_3")
})
output$table <-
renderDataTable({
datatable(data = iris,
options = list(
rowCallback = JS(
"function( nRow, aData) {",
"$(nRow).attr('id', 'tableRow_' +aData[0]);",
"}"
)
))
})
}
# Run the application
shinyApp(ui = ui, server = server)
`
答案1
得分: 0
它适用于 server=FALSE
和 rowCallback
选项而不是 rowCallback
:
output$table <-
renderDT({
datatable(
data = iris,
options = list(
rowId = JS("function(data){return 'tableRow_' + data[0];}")
)
)
}, server = FALSE)
没有尝试过 rowCallback
。
英文:
It works with server=FALSE
and the rowId
option instead of rowCallback
:
output$table <-
renderDT({
datatable(
data = iris,
options = list(
rowId = JS("function(data){return 'tableRow_' + data[0];}")
)
)
}, server = FALSE)
Didn't try with rowCallback
.
答案2
得分: 0
以下是您要翻译的代码部分:
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).
library(DT)
library(shinyBS)
library(shiny)
library(shinyjs) ## needed to tamper with the HTML
ui <- fluidPage(
useShinyjs(),
## need to include at least one bs element in ui
bsTooltip(
"foo",
"This tooltip goes nowhere - it's there to make the tooltips defined with addPopover on the server side work"
) ,
DTOutput("table")
)
server <- function(input, output, session) {
## once the UI is loaded, call shinyBS::addPopover to attach popover to it
session$onFlushed(function() {
addPopover(session,
id = "DataTables_Table_0",
title = "information",
content = "this is the popover on id DataTables_Table_0"
)
for (row in c(1:nrow(iris))) {
addPopover(session,
id = paste0('cell_', row, '_2'),
title = "cell information",
trigger = 'hover',
content = paste('petal width =', iris$Petal.Width[row]),
options = list( container='body')) # container= 'body' makes it so that the popover div doesn't scoot over the next column/mess with the datatable lay-out.
}
})
output$table <-
renderDataTable({
datatable(data = iris[1:10,],
options = list(
columnDefs = list(
list(visible=FALSE, targets=3),
list(targets = "_all",
createdCell = DT::JS("
function(td, cellData, rowData, row, col) {
$(td).attr('id', 'cell_'+(row+1)+'_'+col);
}
")
))))
}, server = FALSE) #server = F is crucial for addpopover to find the new IDs
}
英文:
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).
library(DT)
library(shinyBS)
library(shiny)
library(shinyjs) ## needed to tamper with the HTML
ui <- fluidPage(
useShinyjs(),
## need to include at least one bs element in ui
bsTooltip(
"foo",
"This tooltip goes nowhere - it's there to make the tooltips defined with addPopover on the server side work"
) ,
DTOutput("table")
)
server <- function(input, output, session) {
## once the UI is loaded, call shinyBS::addPopover to attach popover to it
session$onFlushed(function() {
addPopover(session,
id = "DataTables_Table_0",
title = "information",
content = "this is the popover on id DataTables_Table_0"
)
for (row in c(1:nrow(iris))) {
addPopover(session,
id = paste0('cell_', row, '_2'),
title = "cell information",
trigger = 'hover',
content = paste('petal width =', iris$Petal.Width[row]),
options = list( container='body')) # container= 'body' makes it so that the popover div doesn't scoot over the next column/mess with the datatable lay-out.
}
})
output$table <-
renderDataTable({
datatable(data = iris[1:10,],
options = list(
columnDefs = list(
list(visible=FALSE, targets=3),
list(targets = "_all",
createdCell = DT::JS("
function(td, cellData, rowData, row, col) {
$(td).attr('id', 'cell_'+(row+1)+'_'+col);
}
")
))))
}, server = FALSE) #server = F is crucial for addpopover to find the new IDs
}
# Run the application
shinyApp(ui = ui, server = server)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论