在数据表列中启用服务器端智能搜索

问题描述 投票:0回答:1

出于演示目的,我在闪亮中实现了一个示例数据表,其中可以搜索整个数据表(通过使用右上角的搜索字段)和/或在特定列中(通过使用列上方的搜索字段) )。 当数据表在客户端处理时(SERVER = FALSE),智能搜索(例如搜索整个数据表或搜索“Ma W”列汽车显示“Mazda RX4 Wag”)在搜索字段中运行良好。 但是,如果数据表在服务器端处理(SERVER = TRUE),则智能搜索仅适用于整个数据表搜索,但不适用于列搜索。 有没有办法为具有服务器端处理的列启用智能搜索? 预先感谢您。

library(DT)
library(shiny)

ui = fluidPage(
   fluidRow(
      column(width = 12,
             DTOutput("dtable")
      )
   )
)

server = function(input, output, session) {
   data = data.frame(
      car = c("Mazda", "Mazda RX4", "Mazda RX4 Wag", "Ford", "Mercedes"),
      pet = c("dog", "dog", "cat", "cat", "cat")
   )

   output$dtable = renderDT({
      js = c(
         "function(settings) {",
         "  var instance = settings.oInstance;",
         "  var table = instance.api();",
         "  var $inputs = instance.parent().find('.form-group input');",
         "  $inputs.off('keyup search input').on('keyup', function() {",
         "    var value = $(this).val();",
         "    if(value !== '') {",
         "      var index = 1 + $inputs.index(this);",
         "      var column = table.column(index);",
         "      column.search(value, false, true, true).draw();",  # -> regex, smart, caseInsensitive
         "    }",
         "  });",
         "}"
      )
      datatable(
         data, filter = "top",
         options = list(
            dom = "ft",
            columnDefs = list(
               list(targets = "_all", className = "dt-center")
            ),
            search = list(regex = FALSE, smart = TRUE, caseInsensitive = TRUE),  # -> is redundant due to the following up js = c(...) part
            initComplete = JS(js)
         )
      )
   }, server = FALSE)  # -> switch for client-side (server=FALSE) or server-side (SERVER=TRUE) processing
}

shinyApp(ui = ui, server = server)
jquery r shiny dt
1个回答
0
投票

服务器模式的

DT
目前尚未实现对单个列的智能搜索。但是,您可以通过以下两个步骤实现自己的搜索功能来添加功能:

  1. 定义自己的搜索功能进行智能搜索:
smartColumnSearch <-
  function (col, search_string, options = list()) {
    `%||%` <- DT:::`%||%`
    n = length(col)
    if (length(v <- search_string) > 0) {
      if (options$smart %||% TRUE) {
        v = unlist(strsplit(gsub("^\\s+|\\s+$", "", v),
                            "\\s+"))
      }
    }
    
    if (length(v) == 0)
      v = ""
    
    m = if ((nv <- length(v)) > 1)
      array(FALSE, c(length(col), nv))
    else
      logical(n)
    
    if (!identical(v, "")) {
      for (k in seq_len(nv)) {
        i0 = DT:::grep2(
          v[k],
          as.character(col[, drop = TRUE]),
          fixed = !(options$regex %||% FALSE),
          ignore.case = options$caseInsensitive %||%
            TRUE
        )
        if (nv > 1)
          m[i0, k] = TRUE
        else
          m[i0] = TRUE
      }
      which(if (nv > 1)
        apply(m, 1, function(z)
          all(z > 0))
        else
          m)
    }
    else
      seq_len(n)
  }
  1. 搜索是在内部函数
    DT:::dataTablesFilter
    内定义的。这个函数必须修改。致电
fixInNamespace("dataTablesFilter", "DT")

然后将打开一个窗口,您可以在其中更改零件(当前大约在第 45 行左右):

column_opts = list(regex = col[["search"]][["regex"]] != 
                     "false", caseInsensitive = global_opts$caseInsensitive)
dj = data[i, j]
i = i[doColumnSearch(dj, k, options = column_opts)]

对于这个:

column_opts = list(regex = col[["search"]][["regex"]] != 
                     "false", caseInsensitive = global_opts$caseInsensitive,
                   smart = global_opts$smart)
dj = data[i, j]
i = i[smartColumnSearch(dj, k, options = column_opts)]

保存它,它应该在拥有

server = TRUE
的同时起作用。然后,在搜索时调用您的自定义函数,并通过
smart = TRUE
您已在代码中定义的内容启用智能搜索。另请注意,您必须禁用
js
,并且此方法也适用于
server = FALSE

© www.soinside.com 2019 - 2024. All rights reserved.