复选框在 DT Shiny 中的应用

10

我正在尝试将复选框转换成DT表格,并收集有关已选行的信息。
以下是我的代码:

shinyApp(
  ui = fluidPage(
    fluidRow(
      verbatimTextOutput("value1"),
      column(12,
             DT::dataTableOutput('table'),  tags$script(HTML('$(document).on("click", "input", function () {
                       var checkboxes = document.getElementsByName("selected");
                       var checkboxesChecked = [];
                       for (var i=0; i<checkboxes.length; i++) {
                       if (checkboxes[i].checked) {
                       checkboxesChecked.push(checkboxes[i].value);
                      }
                      }
                     Shiny.onInputChange("checked_rows",checkboxesChecked);  })'))
      ))),
  server = function(input, output) {
    library(DT)
    library(glue)
    output$value1 <- renderPrint({ input$checked_rows }) 

    output$table <- DT::renderDataTable({
      iris$checked<-''
      iris$checked[2:5]<-'checked=\"checked\"'
      iris[["Select"]]<-glue::glue('<input type="checkbox" name="selected" {iris$checked} value="{1:nrow(iris)}"><br>')
      datatable(iris,escape=F,rownames=F,  class = 'cell-border compact', 
                options=list(ordering=T,autowidth=F,scrollX = TRUE,
                columnDefs = list(list(className = 'dt-center', targets = "_all"))
                ),
                selection="none"
      ) })})

在此输入图片描述

看起来一切都很好,但是:
1. 当我在复选框中进行选择并更改页面时,所有来自先前页面的数据都会消失。
2. 此外,正如您在verbatimTextOutput(“value1”)中所看到的那样,值得仅从当前页面选择复选框。我如何轮询整个表格,而不仅仅是我看到的页面?

谢谢!

1个回答

9
如下图所示,datatables库(DT包使用的JavaScript库,用于显示漂亮的表格)仅呈现当前页面显示的表格部分(只有10个<tr>标签,但表格包含150行)。
这就是你的脚本不能正确计数的原因,因为DOM中只有表格的部分内容。 此外,DT包默认启用服务器端处理模式(在R中调用?DT::renderDTdatatables.net/manual/server-side查看帮助),这意味着浏览器不仅会提供正在显示的数据。 换句话说,如果启用了服务器端处理模式,在浏览器中甚至无法正确计数。

The screenshot from the developer tools of Chrome

然而,存在替代方法:
  1. 使用参数selection = "multiple":虽然它没有复选框,但基本上就是您需要的;
  2. 如果确实需要复选框,则可以找到rstudio/DT#93commentshinyapps/DT-radio有帮助;
  3. 或者,您可以禁用服务器处理模式,并编写监听器以在复选框被单击时更改表格数据。并像下面这样计数。

代码

$(document).on("click", "input", function () {
      var data = table.data();
      var res = [];
      var elem;
      for (var i=0; i < data.length; i++) {
        elem = $.parseHTML(data[i][6])[0];
        if (elem.checked) {
          res.push(elem.value);
        }
      }
      Shiny.onInputChange("checked_rows", res);  }
  )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接