-
Notifications
You must be signed in to change notification settings - Fork 81
Open
Description
I wanted to have a button inside the Reactable output on the left side of the search box in a shiny app.
The following works, but feels like a hack. Regardless I wanted to leave this here and we can see if we find a better solution.
library(shiny)
library(reactable)
library(htmlwidgets)
move_btn_beside_search <- function(button_id = "go2") {
# JS will run once per widget render, with `el` = widget root element
sprintf("
function(el, x) {
const reactable = el; // widget root
const searchBox = el.querySelector('.rt-search');
const shinyButton = document.getElementById('%s');
if (!reactable || !searchBox || !shinyButton) return;
// Avoid duplicate injection
if (searchBox.parentElement.classList.contains('custom-wrapper')) return;
// Create wrapper
const wrapper = document.createElement('div');
wrapper.className = 'custom-wrapper';
wrapper.style.display = 'flex';
wrapper.style.justifyContent = 'space-between';
wrapper.style.alignItems = 'center';
wrapper.style.marginBottom = '10px';
// Move button and search box into wrapper
wrapper.appendChild(shinyButton);
wrapper.appendChild(searchBox);
// Insert wrapper into Reactable
reactable.insertBefore(wrapper, reactable.firstChild);
}
", button_id)
}
ui <- bslib::page_fillable(
bslib::card(
bslib::input_task_button("go2", "GO2"),
reactableOutput("mytable")
)
)
data <- lapply(seq(1000), \(x) mtcars) |> data.table::rbindlist()
server <- function(input, output, session) {
output$mytable <- renderReactable({
reactable(
data,
searchable = TRUE,
filterable = TRUE
) |>
htmlwidgets::onRender(move_btn_beside_search(session$ns("go2")))
})
observeEvent(input$go2, {
Sys.sleep(2)
showNotification("GO2 clicked")
})
}
shinyApp(ui, server)MaxManek1110
Metadata
Metadata
Assignees
Labels
No labels