在使用R Shiny中的DT包清除后,该列仍显示过滤器

时间:2018-12-06 14:23:57

标签: r shiny dt

此问题在Google Chrome和Firefox中均会发生,但是在Internet Explorer中似乎还可以。如果我有一个数据表,其中有一个因子列并启用了过滤器,则可以选择该列中要过滤的因子。然后,如果我按代理清除了过滤器,则表将重置,但是如果我单击过滤器输入,它仍然显示已选择了过滤器,即使实际上没有选择。

library(shiny)
library(DT)

ui <- fluidPage(
  fluidRow(column(2, DTOutput("table"))),
  fluidRow(actionButton("clear", "Clear Filters"))
)

server <- function(input, output, session) {

  data <- data.frame(LETTERS = c("A", "B", "C"))

  output$table <- renderDT({datatable(data, filter = list(position = "top", clear = FALSE))})

  observeEvent(input$clear, {
    clearSearch(proxy = dataTableProxy("table"))
  })

}

shinyApp(ui = ui, server = server)

此处的表格已过滤为“ A”

enter image description here

然后通过单击“清除过滤器”按钮按代理清除过滤器,表格将取消过滤,并且“ A”上的过滤器将消失。

enter image description here

但是,单击过滤器框会显示“ A”,即使实际上不是,它仍然是选定的过滤器。

enter image description here

这是否甚至可以在DT包中修复?还是Chrome和Firefox的问题?

1 个答案:

答案 0 :(得分:0)

此问题通过在javascript中创建一个函数来清除客户端上的过滤器输入来解决,然后在从DT运行clearSearch函数后调用该过滤器。为简单起见,我创建了一个名为clearColumnSearch的包装函数,可以同时完成这两个工作。

library(shiny)
library(DT)

clearColumnSearch <- function(proxy) {
  clearSearch(proxy = proxy)
  proxy$session$sendCustomMessage(type = "clearColumnSearch", message = list(tableid = proxy$id))
}

ui <- fluidPage(
  fluidRow(column(2, DTOutput("table"))),
  fluidRow(actionButton("clear", "Clear Filters")),
  tags$script(HTML("Shiny.addCustomMessageHandler('clearColumnSearch',
  function(x) {
    // outputId of the DT element
    var table = document.getElementById(x.tableid);
    // filter row of the table element within the DT element
    var tablerow = table.getElementsByTagName('table')[0].rows[1];
    // loop through each cell in the filter row
    for (var i = 0, cell; cell = tablerow.cells[i]; i++) {
      if(['factor', 'logical'].includes(cell.getAttribute('data-type'))) {
        // find the selectize object
        var dropdown = $(cell).find('.selectized').eq(0)[0].selectize;
        // set to blank
        dropdown.setValue('');
      } else if(['number', 'integer', 'date', 'time'].includes(cell.getAttribute('data-type'))) {
        // find the slider object
        var slider = $(cell).find('.noUi-target').eq(0);
        // get the endpoints of the slider
        var min = slider.noUiSlider('options')['range']['min'];
        var max = slider.noUiSlider('options')['range']['max'];
        // set the value of the slider
        slider.val([min, max]);
      } else {}
    }
});"))
)

server <- function(input, output, session) {

  data <- data.frame(LETTERS = c("A", "B", "C"))

  output$table <- renderDT({datatable(data, filter = list(position = "top", clear = FALSE))})

  observeEvent(input$clear, {
    clearColumnSearch(proxy = dataTableProxy("table"))
  })

}

shinyApp(ui = ui, server = server)