R Shiny with datatable, can't clear filters containing certain characters like < and >, but only within my actual app

R Shiny with datatable, can't clear filters containing certain characters like < and >, but only within my actual app

Just to state up front: the R code I'm providing below does NOT exhibit the issue I am having with my actual app -- it exhibits what happens when DataTable filter clearing is working properly. I am having an issue determining what it is about my actual app that is causing it to not work right.

My Shiny app that uses DT DataTables. In the data I am displaying in the table is a column called "Result" which contains text including:

  • <1.3
  • Undetected
  • Positive
  • Negative

The problem is, if I use the DataTable column filter to select <1.3 (or for that matter, anything containing <, > or certain other values) for the filter, it is impossible for me to clear/remove the filter for this item. I.e., the little "x" that appears to the right of a selected item, when I click it, it does not remove <1.3 from the currently active filter. So I can select it, it filters fine, but I cannot unselect it. Nor can I unselect it by using the encircled "x" on the column filter box, which usually removes all active filters.

For values that do not contain <, they are able to be cleared/removed normally either one by one, or using the clear all (encircled "x") button. If for example I select <1.3 and Undetected, if I click the clear all button, it'll remove Undetected but leave <1.3.

The issue I'm having when troubleshooting this is that in a minimal reproduceable example (shown below), this issue does NOT occur. The filter works perfectly, and I can clear values containing <, >, and others, as would be expected. Even when I add a dummy table in my actual app, using the code from the minimal example, the filter problem occurs in that dummy table as well.

So in the actual app I'm working on, I don't know where to look. I have started disabling/removing various bits of code, but it literally feels like I'm taking shots in the dark. The issue in my app even persists creating a simple dummy table with the same values, where everything works fine in the minimal example, and where there is nothing going on with the dummy table other than creating it and displaying it. I am hoping someone here can use these clues to maybe help hone in on the particular problem:

  1. This behavior (the minimal example working fine, and the real app not working) occurs in the same environment (RStudio Pro), with the identical session info when I launch each app. Same packages loaded, same package version (DT is the latest version, 0.33).
  2. In my real app, I created a dummy second table using code identical to the code in the minimal example below, and displayed it alongside my real table. I did this to see if it was something about my real table that was the issue. In the dummy table in my app, the filters still could not be cleared when the value contained certain characters, despite all of them clearing just fine if run in the minimal example.
  3. I checked which other values would also fail to clear, from these specific values: c("<1.3", ">20", "&50", ""quoted"", "'single'","semi;colon", "slash/", "\backslash", "equal=sign","#hash", "comma,separated") Results: a) in the minimal example, I was able to select then clear each of them. b) in the real app, the following failed to clear: "<1.3", ">20", "&50", ""quoted"", "\backslash"

So below is the code which again, does NOT reproduce this issue, because I don't know how to reproduce this issue as it only occurs in my actual app. My actual app does contain other DataTables, so my next effort is going to be removing the other ones to see if that changes anything.

Any ideas of where to start digging/cutting would be appreciated. Thank you.

#these are all the packages used in my real app, which I wanted to load for the minimal example
library(ggplot2)
library(tidyverse)
library(pool)
library(DT)
library(glue)
library(pool)
library(shinyjs)
library(stringr)
library(data.table)
library(lubridate)
library(shinydashboard)
library(rmarkdown)
library(shinyBS)
library(plyr); library(dplyr)
library(stringi)

# UI
ui <- navbarPage(useShinyjs(),
                 tabPanel(
                   titlePanel("DT Filters with Characters"),
                   DTOutput("filtered_table"),
                   actionButton("mybutton","testing")
                 )
)  
# Server
server <- function(input, output, session) {
  
  names <- sample(c("Mike", "Dave", "Anna", "Sara", "John"), 11, replace = TRUE)
  
  results <- c("<1.3", ">20", "&50", "\"quoted\"", "'single'","semi;colon", "slash/", "\\backslash", "equal=sign","#hash", "comma,separated")
  
  data <- data.frame(Name = names, Result = results, stringsAsFactors = TRUE)
  
  output$filtered_table <- renderDT({
  
    datatable(
      data,
      plugins = "input",
      rownames = TRUE,
      filter = "top",
      options = list(pageLength = 10)
    )
  })
}


shinyApp(ui, server)

Answer

After more slicing and dicing, I've found the problem. It's the existence of a selectizeInput.

I'll add a dummy selectizeInput to the minimal code below, which now demonstrates the filtering clearing issue.

Does anyone know how to get the filter clearing working properly while still using a selectizeInput?

#these are all the packages used in my real app, which I wanted to load for the minimal example
library(ggplot2)
library(tidyverse)
library(pool)
library(DT)
library(glue)
library(pool)
library(shinyjs)
library(stringr)
library(data.table)
library(lubridate)
library(shinydashboard)
library(rmarkdown)
library(shinyBS)
library(plyr); library(dplyr)
library(stringi)

# UI
ui <- navbarPage(useShinyjs(),
                 tabPanel(
                   titlePanel("DT Filters with Characters"),
                   DTOutput("filtered_table"),
                   actionButton("mybutton","testing"),
                   selectizeInput("test1", label = "nothing", choices = c("1")) #the problem
                 )
)  
# Server
server <- function(input, output, session) {
  
  names <- sample(c("Mike", "Dave", "Anna", "Sara", "John"), 11, replace = TRUE)
  
  results <- c("<1.3", ">20", "&50", "\"quoted\"", "'single'","semi;colon", "slash/", "\\backslash", "equal=sign","#hash", "comma,separated")
  
  data <- data.frame(Name = names, Result = results, stringsAsFactors = TRUE)
  
  output$filtered_table <- renderDT({
  
    datatable(
      data,
      plugins = "input",
      rownames = TRUE,
      filter = "top",
      options = list(pageLength = 10)
    )
  })
}


shinyApp(ui, server)

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles