簡體   English   中英

使用 initComplete 在 Shiny 應用程序中使用 Javascript 的目標特定 DT::datatable 表

[英]Target specific DT::datatable table with Javascript in Shiny app using initComplete

假設我們有一個帶有兩個DT表的 Shiny 應用程序,我們希望在呈現表后使用一些 Javascript 對其進行修改。 我們將不同的上標附加到每個表中的 header ; 我們 append 上標 '1' 到表 1,上標 '2' 到表 2。這個 JS 是使用initComplete觸發的,即當表格被渲染時。

我的 JS 技能不存在,所以我目前正在選擇表 header 到 append 到th:contains(<header-string>) 例如,將上標附加到包含字符串“Sepal”的表 header:

jsc <- '
    function(settings, json) {
        $("th:contains(\'Sepal\')").append(\'<sup>1</sup>\');
    }
'

由於我們需要為不同的表使用不同的上標,因此我們需要為每個表定義單獨的 Javascript 來觸發。 這個問題是表頭都包含我正在尋找的字符串,導致兩個上標都附加到兩個表頭。

假設不同的表在相關表 header 中總是包含相同的字符串(因此th:contains將不是一個可行的選項——表頭可能完全相同),我們如何 select 應用特定的表Javascript 到? 我們無法為datatable應用程序中的數據表調用提供elementId ,例如,

output$table1<- renderDT({datatable(iris, elementId = 'table1')})

導致警告

renderWidget(instance) 中的警告:忽略顯式提供的小部件 ID“table1”; Shiny 不使用它們

下面是一個可重現的示例。 這兩個表具有相同的列名,因此 Javascript 將兩個上標附加到每個表的Sepal.Length header 上。 The desired output is to have the first table's Sepal.Length header with a superscripted '1', and the second table's Sepal.Length header with a superscripted '2', while the current example appends '12' to both table's headers.

有趣的是,當應用程序在 RStudio 查看器中打開時,僅運行第一個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[, c('Species', 'Sepal.Length')],
            options(
                initComplete = JS(jsc2)  
            )
        )
    })
}

options(shiny.launch.browser = TRUE)
shinyApp(ui, server)

請注意,我知道我們可以使用escape = FALSE直接將<sup>1</sup>寫入表頭,但是還有其他 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\')")將選擇所有包含Sepalth ,並且可以在整個頁面上找到。

但是這種方式如果更改id,則需要更改JS代碼。 這樣做更實際:

jsc <- '
    function(settings, json) {
        var $table = $(this.api().table().node());
        $table.find("th:contains(\'Sepal\')").append(\'<sup>1</sup>\');
    }
'

完整代碼:

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[, c('Species', 'Sepal.Length')],
              options = list(
                initComplete = JS(jsc)
              )
    )
  })
  
  output$table2 <- renderDT({
    datatable(iris[, c('Species', 'Sepal.Length')],
              options = list(
                initComplete = JS(jsc2)  
              )
    )
  })
}

shinyApp(ui, server)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM