Search code examples
rshinydt

Batch searching regex in Shiny DT datatables with spaces (not pipes)


Following on from this post can anyone please tell me if it's possible to implement a way to search an interactive Shiny DT datatable where keywords are separated by spaces and not pipes? Users of my apps will have lists of genes separated by spaces and adding pipes will defeat the point of making the app user friendly.

Example code:

## example taken from https://rstudio.github.io/DT/007-search.html
library(DT)
mtcars2 = mtcars[, c(1:5, 9)]
mtcars2$am = factor(mtcars$am, c(0, 1), c('automatic', 'manual'))
dt <- datatable(
  mtcars2, colnames = c('model' = 1),
  filter = list(position = 'top', clear = FALSE),
  options = list(
    search = list(regex = TRUE, caseInsensitive = TRUE),
    pageLength = 5
  )
)


## ----simple Shiny app with datatable----
ui <- fluidPage(
  fluidRow(
    DT::dataTableOutput("table")
  )
)

server <- function(input, output) {
  output$table <- DT::renderDataTable(dt)
}

shinyApp(ui = ui, server = server)

works well how to work

> sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats4    parallel  stats     graphics  grDevices utils     datasets  methods  
[9] base     

other attached packages:
 [1] ggplot2_3.3.0        DT_0.13              rsconnect_0.8.16     shinythemes_1.1.2   
 [5] dplyr_0.8.5          shiny_1.4.0.2        BiocParallel_1.20.1  MLInterfaces_1.66.5 
 [9] cluster_2.1.0        annotate_1.64.0      XML_3.99-0.3         AnnotationDbi_1.48.0
[13] IRanges_2.20.2       MSnbase_2.12.0       ProtGenerics_1.18.0  S4Vectors_0.24.4    
[17] mzR_2.20.0           Rcpp_1.0.4.6         Biobase_2.46.0       BiocGenerics_0.32.0 

Solution

  • Here is a way:

    library(shiny)
    library(DT)
    
    callback <- '
    $("div.search").append($("#mySearch"));
    $("#mySearch").on("keyup redraw", function(){
      var splits = $("#mySearch").val().split(" ").filter(function(x){return x !=="";})
      var searchString = "(" + splits.join("|") + ")";
      table.search(searchString, true).draw(true);
    });
    '
    
    ui <- fluidPage(
      tags$head(tags$style(HTML(".search {float: right;}"))),
      br(),
      tags$input(type = "text", id = "mySearch", placeholder = "Search"),
      DTOutput("dtable")
    )
    
    server <- function(input, output){
    
      output[["dtable"]] <- renderDT({
        datatable(
          iris[c(1,2,51,52,101,102),],
          options = list(
            dom = "l<'search'>rtip"
          ),
          callback = JS(callback)
        )
      }, server = FALSE)
    
    }
    
    shinyApp(ui, server)