问题描述
假设我们有一个带有两个DT
表的Shiny应用程序,我们希望在渲染表后使用一些Javascript对其进行修改。我们在每个表的标题中附加一个不同的上标;我们在表1上添加上标'1',在表2上添加上标'2'。此JS是使用initComplete
触发的,即在渲染表时触发。
我的JS技能不存在,因此我目前正在选择要附加到th:contains(<header-string>)
的表头。例如,将上标附加到包含字符串'Sepal'的表标题中:
jsc <- '
function(settings,json) {
$("th:contains(\'Sepal\')").append(\'<sup>1</sup>\');
}
'
由于我们需要为不同的表使用不同的上标,因此我们需要定义单独的Javascript以为每个表触发。问题是表头都包含我要查找的字符串,导致两个上标都附加到两个表头上。
假设不同的表在相关的表头中始终包含相同的字符串(因此th:contains
将不是一个可行的选择-表头可能完全相同),我们如何选择适用于Java的特定表?我们无法在“闪亮”应用程序中为elementId
调用提供datatable
,例如
output$table1<- renderDT({datatable(iris,elementId = 'table1')})
产生警告
renderWidget(instance)中的警告: 忽略显式提供的小部件ID“ table1”;闪亮不使用它们
下面是一个可复制的示例。这两个表具有相同的列名,因此Javascript将这两个上标附加到每个表的Sepal.Length
标题中。理想的输出结果是第一个表的Sepal.Length
标头带有上标“ 1”,第二个表的Sepal.Length
标头带有上标“ 2”,而当前示例在两个表的后缀中都附加了“ 12”标头。
很有趣,当在RStudio Viewer中打开应用程序时,仅运行第一个initComplete
,因此两个表头均带有上标'1'。我忽略了这一点,并在Firefox和Chrome上查看了结果。
library(shiny)
library(DT)
jsc <- '
function(settings,json) {
$("th:contains(\'Sepal\')").append(\'<sup>1</sup>\');
}
'
jsc2 <- '
function(settings,json) {
$("th:contains(\'Sepal\')").append(\'<sup>2</sup>\');
}
'
ui <- {
fluidPage(
fluidRow(
column(6,DTOutput('table1')
),column(6,DTOutput('table2')
)
)
)
}
server <- function(input,output,session) {
output$table1 <- renderDT({
datatable(iris[,c('Species','Sepal.Length')],options(
initComplete = JS(jsc))
)
})
output$table2 <- renderDT({
datatable(iris[,options(
initComplete = JS(jsc2)
)
)
})
}
options(shiny.launch.browser = TRUE)
shinyApp(ui,server)
请注意,我知道我们可以使用<sup>1</sup>
将escape = FALSE
直接写到表头中,但是要在表上执行其他JS函数,因此这种方法不适合。谢谢您的任何建议。
解决方法
首先,options
必须是一个列表:
datatable(iris[,c('Species','Sepal.Length')],options = list(
initComplete = JS(jsc)
)
)
现在,您可以通过在jQuery选择器中提供ID来定位表:
jsc <- '
function(settings,json) {
$("#table1 th:contains(\'Sepal\')").append(\'<sup>1</sup>\');
}
'
否则,$("th:contains(\'Sepal\')")
选择包含th
的所有Sepal
,这些jsc <- '
function(settings,json) {
var $table = $(this.api().table().node());
$table.find("th:contains(\'Sepal\')").append(\'<sup>1</sup>\');
}
'
可以在整个页面上找到。
但是,如果您更改ID,则这种方法需要更改JS代码。这样做更实用:
library(shiny)
library(DT)
jsc <- '
function(settings,json) {
var $table = $(this.api().table().node());
$table.find("th:contains(\'Sepal\')").append(\'<sup>1</sup>\');
}
'
jsc2 <- '
function(settings,json) {
var $table = $(this.api().table().node());
$table.find("th:contains(\'Sepal\')").append(\'<sup>2</sup>\');
}
'
ui <- {
fluidPage(
fluidRow(
column(6,DTOutput('table1')
),column(6,DTOutput('table2')
)
)
)
}
server <- function(input,output,session) {
output$table1 <- renderDT({
datatable(iris[,options = list(
initComplete = JS(jsc)
)
)
})
output$table2 <- renderDT({
datatable(iris[,options = list(
initComplete = JS(jsc2)
)
)
})
}
shinyApp(ui,server)
完整代码:
path = """{'ResponseMetadata': {'Flag': 'Processed','Message': 'File Ingested successfully','INGEST_PATH': ['inward/emr_batch/manual_cars/xy99',""manual_cars/xy99/2020/08/12/145938/ABC KPI's Jan 2018.csv""]}}"""