Highlight word in DT in shiny based on regex
Instead of relying on datatable's search functionality you can create a reactive
element that first filters by the input, and then replaces the matching words with the same word embedded in a <span style="background-color:yellow;">
tag. This should allow more search flexibility via more complex regex.
You'll need to add escape = F
to datatable
so the HTML tag is interpreted properly. I've added options = list(dom = "lt")
to datatable
to remove the datatable's search field and direct attention to the left search field.
The filtering criteria are left fairly fuzzy to keep the table from disappearing until a perfect match is found – i.e. the table shouldn't disappear when you type "o" because there's no perfect match, and then reappear at "on". The highlights then only appear if a matching word is found, i.e. on
, On
, and on.
, but not stone
, scone
, etc. Here's a glimpse of what it looks like:
And here's the code. Note that I use dplyr's filtering and mutating functions because they can easily be applied to multiple columns via their *_all
variants:
library(shiny)
library(DT)
library(data.table)
library(dplyr) # For `filter_all` and `mutate_all`.
example_data <- iris
# data.table(words = c("on", "scone", "wrong", "stone"),
# description = c("The word on", "Scone is not on.", "Not on either", "Not here at all"))
ui = shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
textInput("word_select", label = "Word to search")
),
mainPanel(
dataTableOutput("word_searched")
)
)
))
server = shinyServer(function(input, output, session) {
# This is your reactive element.
df_reactive <- reactive({
example_data %>%
# Filter if input is anywhere, even in other words.
filter_all(any_vars(grepl(input$word_select, ., T, T))) %>%
# Replace complete words with same in HTML.
mutate_all(~ gsub(
paste(c("\\b(", input$word_select, ")\\b"), collapse = ""),
"<span style='background-color:yellow;'>\\1</span>",
.,
TRUE,
TRUE
)
)
})
# Render your reactive element here.
output$word_searched <- renderDataTable({
datatable(df_reactive(), escape = F, options = list(dom = "lt"))
})
})
shinyApp(ui = ui, server = server)