-
Notifications
You must be signed in to change notification settings - Fork 81
Description
Hi @glin,
I'm currently building a Shiny application using the reactable package where the main table displays data and, upon clicking a row, a nested subtable (details) is revealed. My objective is to implement a single global search field that filters both the main table and its nested subtable. I’ve explored using a hidden column that consolidates the nested data into the main table, but I find it to be a workaround rather than an ideal solution.
I reviewed the code provided in [Issue #225](#225), yet I'm wondering if there’s a simpler or more direct approach using the reactable JavaScript API that allows searching across fields in both the main table and the nested subtable without resorting to hidden columns. Is there a built-in option or a recommended method to achieve this global filtering functionality for nested tables?
This is an example code:
library(shiny)
library(reactable)
library(dplyr)
library(htmltools)
# Example data frames
df1 <- data.frame(
ID = c("A1", "A2", "A3"),
Name = c("Jim", "Mary", "Peter"),
Value = c(10, 20, 30),
stringsAsFactors = FALSE
)
df2 <- data.frame(
ID = c("A1", "A1", "A2", "A3", "A3"),
Description = c("Item 1", "Item 2", "Detail for A2", "Detail X", "Detail Y"),
Quantity = c(5, 7, 15, 25, 35),
stringsAsFactors = FALSE
)
# Add a hidden column to df1 with concatenated information from df2
df_main <- df1 %>%
left_join(
df2 %>%
group_by(ID) %>%
summarise(Details = paste(paste0(Description, " (", Quantity, ")"), collapse = ", ")),
by = "ID"
)
ui <- fluidPage(
# Page title
titlePanel("Main Table with Nested Subtable and Global Search"),
# Single search box to filter the main table (which includes the hidden field)
div(
tags$input(
id = "search_input",
type = "search",
placeholder = "Search in both levels...",
# The search is applied to the main table whose elementId is "main_table"
oninput = "Reactable.setSearch('main_table', this.value)"
)
),
# Main table output
reactableOutput("main_table")
)
server <- function(input, output, session) {
output$main_table <- renderReactable({
reactable(
df_main,
elementId = "main_table", # ID to be used with the JavaScript API
searchable = FALSE, # Use external JS search
defaultPageSize = 5,
pagination = TRUE,
columns = list(
ID = colDef(name = "ID", align = "center", width = 80),
Name = colDef(name = "Name"),
Value = colDef(name = "Value", align = "center"),
# Hidden column: it remains in the data frame for search purposes,
# but is hidden via CSS.
Details = colDef(
style = list(display = "none"),
headerStyle = list(display = "none")
)
),
# Define the details (nested subtable) shown when a row is clicked
details = function(index) {
# Filter df2 to get records with an ID matching the selected row
subdata <- df2 %>% filter(ID == df_main$ID[index])
if (nrow(subdata) == 0) return(NULL)
# Create the nested subtable using reactable.
reactable(
subdata,
searchable = FALSE,
pagination = FALSE,
columns = list(
ID = colDef(name = "ID", align = "center", width = 60),
Description = colDef(name = "Description"),
Quantity = colDef(name = "Quantity", align = "center")
)
)
}
)
})
}
shinyApp(ui, server)
Thank you in advance for your guidance.
Best regards,
Sergio